【问题标题】:In C++03, how to conditionally declare a static data member of a template class, based on type traits在 C++03 中,如何根据类型特征有条件地声明模板类的静态数据成员
【发布时间】:2018-08-11 21:58:36
【问题描述】:

背景

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

(+)

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

如果类型特征dummy_trait&lt;T&gt;::value超过模板参数 Tfootrue,那么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&lt;T&gt;::valuefalse(尽管foo 中没有value 成员),而如果使用 (B),则根本不可能进行此类实例化。

【问题讨论】:

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


    【解决方案1】:

    除了以下两种方法(利用 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)。

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

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

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

    【讨论】:

    • 谢谢,这是一个不错的选择,而且我目前使用的 linter 可能会更好,即使是最简单的模板元编程结构也会脱轨。关于 (B) 的要点,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多