什么是专业化特质成员最便宜的方式

时间:2015-07-18 08:59:48

标签: c++ templates template-specialization typetraits c++03

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

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,以防万一。)

2 个答案:

答案 0 :(得分:7)

可以明确地专门化类模板的成员:

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>"; }
};

答案 1 :(得分:-1)

为什么不使用功能?

auto calendar = boost::python::import( "calendar" );
auto leap = calendar.attr("isleap")("2015");
相关问题