提问人:sbi 提问时间:7/18/2015 最后编辑:dypsbi 更新时间:7/18/2015 访问量:89
使特征成员专业化的最便宜方法是什么
What's the cheapest way to specialize a traits member
问:
我有一个特征类,它应该只提供有关其他类型的一个信息(以字符串的形式):
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
我试图摆弄显式的专用化,但未能想出一种不会让编译器向我吐出有毒错误消息的语法。
笔记:
- 我知道我可以把它隐藏在宏后面。我仍然很好奇。
- 这需要在具有 GCC 4.1 的嵌入式平台上进行编译。所以C++03就是我们所拥有的一切。(Boost 很好,但对于有限的 Posix 支持,我们只能使用 1.52,以防万一。
答:
-1赞
Benilda Key
7/18/2015
#1
为什么不使用函数?
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"; }
};
评论
0赞
sbi
7/18/2015
因为一般来说,常量比函数调用更普遍可用?(顺便说一句,如果我这样做,我只会声明主模板,而不会定义它。
7赞
dyp
7/18/2015
#2
可以显式地对类模板的成员进行专用化:
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>"; }
};
评论
0赞
sbi
7/18/2015
我发现,一般来说,常量比函数调用更普遍有用(参见)。对于字符串来说,它很可能没有太大的区别,但无论如何我都想知道如何做到这一点。std::numeric_limits<>::max()
0赞
dyp
7/18/2015
@sbi 这是第二个特征,只是为了提供字符串。你仍然可以把你原来的特质作为一个“适配器”。请参阅我更新的答案。如果您有几个特征都需要专业化,这可能会更方便。
0赞
sbi
7/18/2015
明白了。这个答案很全面。谢谢!
评论