Подтвердить что ты не робот

Есть ли способ выполнить "if (condition) typedef..."

Я хотел бы выполнить typedef, тогда и только тогда, когда выполняется условие времени компиляции. Если условие не выполнено, то typedef должно выполняться вообще.

Возможно ли это в С++ 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.

4b9b3361

Ответ 1

Другим способом может быть переход от специализации базового класса

// 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>’
 }

Ответ 2

К сожалению, желаемый синтаксис невозможен, поскольку имена, которые передаются в экземпляр шаблона, должны быть уже определены. В вашем случае myType1 и myType2 ничего не назвали бы из точки компилятора. Однако, если вы не настаиваете на упомянутом выше синтаксисе, вы можете попытаться использовать 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]


Edit:

Еще один способ, который пришел мне на ум (используя использование параметра шаблона по умолчанию):

#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]

Ответ 3

Подобно std:: enable_if, вы можете удалить свой класс из шаблона, который делает ваш typedef, если вы хотите использовать свои собственные имена и не должны выполнять A:: mytype1:: type. Недостатком является то, что вам нужно будет спуститься с нескольких структур, если вы хотите сделать это много.

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
}