使特征成员专业化的最便宜的方法是什么

What's the cheapest way to specialize a traits member

我有一个特征 class 应该只提供一个关于其他类型的信息(以字符串的形式):

template<typename T>
struct some_traits {
    static const char* const some_string;
};

我需要为每种类型提供 some_string 的特殊实例。我知道如何做到这一点的常用方法是仅声明 some_traits,然后编写特化:

template<typename T>
struct some_traits;

template<>
struct some_traits<blah> {
    static const char* const some_string;
};
const char* const some_traits<blah>::some_string = "blah string";

然而,这是很多代码,而我只需要一个专门的 some_string。有没有办法简化这个?

我曾尝试 fiddle 使用显式特化,但未能提出一种不会让编译器向我吐出恶毒错误消息的语法。

备注:

为什么不用函数?

template<typename T>
struct some_traits {
    static const char* const some_string();
};

template<>
struct some_traits<blah> {
     static const char* const some_string() { return "blah string"; }
};

可以显式特化 class 模板的成员:

template<typename T>
struct some_traits {
    static const char* const some_string;
};

template<>
char const* const some_traits<int>::some_string = "int";

这应该会稍微减少声明新专业化的开销。但是,此技术不能应用于部分专业化:

template<typename T> struct foo {};
template<typename T>
char const* const some_traits<foo<T>>::some_string = "foo<T>"; // error

... 也就是说,除非您为 some_traits 添加部分专业化:

template<typename T>
struct some_traits<foo<T>> {
    char const* const some_string;
};

两种选择:

(1) 使用 ADL 和函数

template<typename T> struct some_string_tag {};

template<typename T>
struct some_traits {
    static const char* const some_string;
};
template<typename T>
char const* const some_traits<T>::some_string = get_string(some_string_tag<T>());

专业化可以写成:

char const* get_string(some_string_tag<int>) { return "int"; }

部分专业化为:

template<typename T>
char const* get_string(some_string_tag<foo<T>>) { return "foo<T>"; }

(在这种情况下,some_traits 是自定义如何找到字符串的一个点,它提供了对字符串作为变量的方便访问。)

(2) 使用内联函数的第二个特征

template<typename T>
char const* const some_traits<T>::some_string = some_traits_X<T>::get_string();

template<typename T> struct some_traits_X {
    // provide: static char const* get_string();
};

template<>
struct some_traits_X<int> {
    static char const* get_string() { return "int"; }
};

template<typename T>
struct some_traits_X<foo<T>> {
    static char const* get_string() { return "foo<T>"; }
};