web-dev-qa-db-ja.com

「if(条件)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を探しています。

18
ManuelAtWork

別の方法は、基本クラスの専門化から渡すことです。

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

残念ながら、テンプレートのインスタンス化に渡される名前はすでに定義されている必要があるため、必要な構文を使用することはできません。あなたの場合、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;
}

[ライブデモ]


編集:

私の頭に浮かんださらに別の方法(デフォルトのテンプレートパラメータで使用する):

#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;
}

[ライブデモ]

15
W.F.

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
}
2
Erroneous