在 C++03 中,如何根据类型特征有条件地声明模板 class 的静态数据成员

In C++03, how to conditionally declare a static data member of a template class, based on type traits

背景

考虑到我想 在 C++03 中实现以下人为构造:

(+)

template< typename T >  // parameter list must contain T but may otherwise modified
struct foo;

If the type trait dummy_trait<T>::value over the template parameter T of foo is true, then foo should contain a static data member named value, of type T, initialized with the integer literal expression 42; otherwise there should be no static data member named value.

例如以下 dummy_trait(实际虚拟特征可能不同):

template< typename T >
struct dummy_trait { static const bool value = false; };

template<>
struct dummy_trait<int> { static const bool value = true; };

问题


我自己的方法

使用助手

template< bool B, typename T = void >
struct enable_if {};

template< typename T >
struct enable_if<true, T> { typedef T type; };

例如使用部分 class 模板专业化:

// (A)
template< typename T, typename Enable = void >
struct foo {};

template< typename T >
struct foo<T, typename enable_if<dummy_trait<T>::value>::type > { 
    static const T value = 42; 
};

或者例如利用 SFINAE 在静态数据成员的声明中引入条件性(特征)错误:

// (B)
template< typename T >
struct foo {
    static const typename enable_if<
        dummy_trait<T>::value, T >::type value = 42;
};

如果我没记错的话,上面的 (A) 将允许使用 foo 也用于类型 T 的实例化,其中 dummy_trait<T>::valuefalse(尽管将没有 foovalue 成员),而如果使用 (B).

则根本不可能进行此类实例化

Are there any other (possibly more appropriate) alternatives to implement (+), in addition to the two approaches below (leveraging SFINAE)?

与您的解决方案 (A) 差别不大,但是...您可以通过继承获得结果

template <typename T>
struct foo : public bar<T>
 { };

其中bar如下

template <typename T, bool = dummy_trait<T>::value>
struct bar { };

template <typename T>
struct bar<T, true> { static const T value = 42; };

您还可以将 bar 视为获得 foo.

的更简单方法(无 enable_if

Are there any pitfalls or aspects to carefully bear in mind using any of the two approaches below?

我看到的唯一陷阱是您刚才看到的那个:(B) 方法不起作用,因为当 dummy_trait<T>::valuefalse 时您无法定义 foo

我的意思是...(B) 不是 SFINAE,因为替换失败,在这种情况下,一个错误。