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

时间:2018-08-11 21:58:36

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

背景

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

  

(+)

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

如果模板参数上的类型特征dummy_trait<T>::value   T中的footrue,则foo应该包含静态数据成员   类型为value的名为T的实例,它用整数文字表达式42初始化;否则应该没有静态数据   名为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; };

例如使用部分类模板专门化:

// (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(尽管不能是value的{​​{1}}成员),而如果使用foo,则根本不可能进行这样的实例化。

1 个答案:

答案 0 :(得分:4)

  

除了以下两种方法(利用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是获得enable_if的更简单方法(没有foo)。

  

使用以下两种方法中的任何一种,是否有需要牢记的陷阱或方面?

我看到的唯一陷阱是您刚刚看到的陷阱:(B)方法不起作用,因为当foodummy_trait<T>::value时您无法定义false

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