有没有办法执行" if(condition)typedef ..."

时间:2016-12-01 09:56:46

标签: c++ c++11 templates typedef

当且仅当满足编译时条件时,我想执行typedef。如果不满足条件,则根本不应执行typedef

这在C ++ 11中是否可行?

示例:

class A {
  std::conditional_typedef<true,int,myType1>; // Performs "typedef int myType1".
  std::conditional_typedef<false,int,myType2>; // Does nothing at all.
};

我正在寻找这个虚构的std::conditional_typedef

3 个答案:

答案 0 :(得分:19)

另一种方法可以从基类的专业化传递

// foo is a light struct (only a typedef or not at all) that can be
// developed in two versions

template <bool>
struct foo;

template <>
struct foo<true>
 { typedef int myType1; }; // or using myType1 = int;

template <>
struct foo<false>
 { };

template <bool B>
struct bar : public foo<B> // B can be a type_traits value derived
                           // from template arguments for bar
 {
   // potential complex struct or class, developed only one time 
 };


int main()
 {
   bar<true>::myType1 mt1 { 1 };
   // bar<false>::myType1 mt2 { 1 }; error: ‘myType1’ is not a member of ‘bar<false>’
 }

答案 1 :(得分:15)

不幸的是,由于必须已经定义了传递给模板实例化的名称,因此无法使用所需的语法。在您的情况下,myType1myType2不会从编译器的角度命名任何内容。但是,如果您不坚持您提到的语法,可以尝试使用std::enable_if,如下所示:

#include <type_traits>

struct A {
    struct myType1: std::enable_if<true, int> { }; //std::conditional_typedef<true,int,myType1>; // Performs "typedef int myType1".
    struct myType2: std::enable_if<false, int> { }; //std::conditional_typedef<false,int,myType2>; // Does nothing at all.

};

int main() {
    A::myType1::type i;
    //A::myType2::type i2; // causes error: no type named 'type' in 'A::myType2'
    (void)i;
}

[live demo]

修改

另一种我想到的方式(利用默认模板参数使用):

#include <type_traits>

struct A {
    template <class T = int>
    using myType1 = typename std::enable_if<true, T>::type;
    template <class T = int>
    using myType2 = typename std::enable_if<false, T>::type;
};

int main() {
    A::myType1<> i;
    //A::myType2<> j;
    (void)i;
}

[live demo]

答案 2 :(得分:2)

与std :: enable_if类似,如果你想使用你自己的名字而不必做A :: mytype1 :: type,你可以从你的typedef模板中继承你的类。缺点是,如果你想要做很多事情,你必须从多个结构中下降。

namespace impl {
    template<bool, typename> struct A;
    template<typename T> struct A<true, T>{ typedef T mytype1; };
    template<typename T> struct A<false, T> {};
}

struct A : public impl::A<condition, int> {
    //If condition is met, then ::mytype1 will be defined as a typedef int
};

int main() {
    A::mytype1 i; //Will fail if condition wasn't met
}