【问题标题】:Can I use enable_if together with typedef?我可以将 enable_if 与 typedef 一起使用吗?
【发布时间】:2016-11-20 16:36:30
【问题描述】:

我想定义一个类型取决于某些条件的变量。我想要这样的东西:

typedef typename enable_if<cond, int>::type Type;
typedef typename enable_if<!cond, double>::type Type;

但是编译器说我重新定义了类型。

我该怎么做?

【问题讨论】:

    标签: c++ templates typedef enable-if redefine


    【解决方案1】:

    我可以将enable_if 与 typedef 一起使用吗?

    不,你不能。 std::enable_if 如果条件为假,则类型未定义。只有条件为真,才定义成员type

    template< bool B, class T = void >
     struct enable_if;
    

    如果Btruestd::enable_if有一个公共成员typedef类型,等于T;否则,没有成员 typedef。

    为了使 typedef 正常工作,它需要一个类型来处理两种情况,当条件为真和为假时。实施enable_if 以协助与 SFINAE 相关的场景。

    那么

    我该怎么做?

    使用std::conditional。 Conditional 将包含一个成员 typedef (type) 用于条件的 truefalse 结果。

    template< bool B, class T, class F >
     struct conditional;
    

    提供成员typedef类型,如果B在编译时定义为true,则定义为T,如果Bfalse,则定义为F

    因此,以下就足够了;

    typedef typename std::conditional<cond, int, double>::type Type;
    

    或者更简洁的;

    using Type = std::conditional_t<cond, int, double>;
    

    【讨论】:

    • 将 SFINAE 与 typedef 一起使用真的不合法吗,例如template &lt;typename T&gt; class C { typedef std::enable_if&lt;trait&lt;T&gt;::value, blah&gt; type; };?
    • 不是真的,看这里; godbolt.org/g/2YT04Q。在模板推论的直接上下文之外,我也没有真正看到它。问题是当条件为假时会发生什么,typedef 没有别名类型。 SFINAE 用于处理函数模板的重载解析,en.cppreference.com/w/cpp/language/sfinae
    【解决方案2】:

    你需要使用std::conditional:

    #include <type_traits>
    
    // c++11:
    typedef typename std::conditional<cond, int, double>::type Type;
    
    // c++14:
    typedef std::conditional_t<cond, int, double> Type;
    

    还要注意,从 c++11 开始,您可以使用 using 关键字作为类型和模板别名(我认为更简洁一些):

    // c++11
    using Type = typename std::conditional<cond, int, double>::type;
    
    // c++14
    using Type = std::conditional_t<cond, int, double>;
    

    【讨论】:

      猜你喜欢
      • 2021-08-01
      • 2023-03-25
      • 2020-08-04
      • 2018-10-23
      • 2011-02-22
      • 2021-03-16
      • 2019-01-25
      • 2011-06-11
      • 2017-02-20
      相关资源
      最近更新 更多