Quero me especializar std::formatter
dentro do meu namespace. No entanto, isso não funciona como eu gostaria (variante 1). Funciona fora do namespace (variante 3), bem como com uma solução alternativa dentro do namespace (variante 2).
#include <format>
#include <iostream>
#include <string>
#include <type_traits>
class Class {};
#define VARIANT 1
namespace Namespace {
#if VARIANT == 1
template <>
struct std::formatter<Class> : std::formatter<std::string> {
auto format(const Class& Class, auto& context) const {
return std::formatter<std::string>::format("CLASS", context);
}
};
#endif
#if VARIANT == 2
template <typename T>
requires std::same_as<T, Class>
struct std::formatter<T> : std::formatter<std::string> {
auto format(const Class& Class, auto& context) const {
return std::formatter<std::string>::format("CLASS", context);
}
};
#endif
} // namespace Namespace
#if VARIANT == 3
template <>
struct std::formatter<Class> : std::formatter<std::string> {
auto format(const Class& Class, auto& context) const {
return std::formatter<std::string>::format("CLASS", context);
}
};
#endif
int main() { std::cout << std::format("{}", Class()) << std::endl; }
Isto está no x64 msvc v19.40 VS17.10. gcc compila apenas a variante 3.
Então, minhas perguntas são: quais são as formas portáteis e em conformidade com os padrões de especialização std::formatter
dentro de namespaces (ou em geral)?
Não há nenhuma.
Você só pode especializar um modelo de classe em locais onde possa definir o modelo primário. Ou seja, você precisa fazer o seguinte (no escopo global):
Ou você faz isso (dentro de
std
):Mas você não pode fazer isso ou algo parecido:
De forma mais geral, dado algo como:
Todas estas opções estão corretas:
Mas não em nenhum outro lugar.