Но с частичной специализацией - это проблема - из-за меняющегося характера различных библиотек (включая стандартную библиотеку C++) и того, какие частичные специализации уже включены (а иногда даже детали внедрения того, как они реализованы - только то, что они совпадают).
У меня есть библиотека с кучей предоставленных типов, которая пытается работать с различными std версии C++ (20, 23, 26) и эти типы работают с форматтером.
Из Стройки 'ToString.h'
Код: Выделить всё
// Does type 'T' support the Stroika ToString() API
template
concept IToString = requires (T t) { { ToString (t) } -> convertible_to; };
...
template
struct ToStringFormatter /* : std::formatter*/{...}
тогда используйте ToStringFormatter (не говоря уже о пространствах имен для простоты):
Код: Выделить всё
template
requires (!std::formattable && IToString)
struct std::formatter : ToStringFormatter {};
Похоже, что это самый простой и естественный подход, но это не так. работайте над Visual Studio
(ошибка C7608: атомарное ограничение должно быть постоянным выражением)
предположительно потому, что определение фактически меняет значение, возвращаемое ограничением.
ИЛИ< /p>
Код: Выделить всё
template
struct std::formatter : ToStringFormatter {};
Итак, я остановились на специальном подходе:
Код: Выделить всё
template
concept IUseToStringFormatterForFormatter_ =
// most user-defined types captured by this rule - just add a ToString() method!
requires (T t) {
{
t.ToString ()
} -> convertible_to;
}
// Stroika types not captured by std-c++ rules
or Common::IKeyValuePair or Common::ICountedValue
// c++ 23 features which may not be present with current compilers
// value with clang++16 was 202101L and cpp2b and libc++ (ubuntu 23.10 and 24.04) flag... and it had at least the pair code supported.
// this stuff needed for clang++-18-debug-libstdc++-c++23
#if !__cpp_lib_format_ranges
#if !qHasFeature_fmtlib or (FMT_VERSION < 110000)
or (ranges::range and
not Configuration::IAnyOf)
#endif
#endif
// sadly MSFT doesn't support all, and doesn't support __cplusplus with right value
// 202302L is right value to check for C++ 23, but 202101L needed for clang++16 ;-(
#if _MSC_VER || __cplusplus < 202101L /*202302L 202100L 202300L*/ || (__clang__ != 0 && __GLIBCXX__ != 0 && __GLIBCXX__
Подробнее здесь: [url]https://stackoverflow.com/questions/78774217/how-to-extend-stdformatter-without-sometimes-introducing-conflicts-can-concep[/url]
Мобильная версия