1

SFINAE を使用して、特性クラスにエイリアスが存在するかどうかに応じて、別のクラスにエイリアス テンプレートを設定できるかどうか疑問に思っていました。

template<class T>
struct Foo_Traits;

struct Foo1;

template<>
struct Foo_Traits<Foo1>
{
  using type1 = Bar1;
  using type2 = Bar2;
};

struct Foo2;

template<>
struct Foo_Traits <Foo2>
{
  using type1 = Bar3;
};

基本的に、2 つのクラス Foo1 と Foo2 と、この場合は単純化するために型エイリアスを定義するそれらの特性クラスがあります。すべての場合に type1 エイリアスがあり、場合によっては type2 があります。

別のクラス (私の場合、実際には Foo の基本クラス) で、これらの型のエイリアスを設定したいと考えています。

template<typename ImplT>
class FooBase
{
   using T1 = typename Foo_Traits<ImplT>::type1;

   using T2 = typename std::conditional< defined<typename Foo_Traits<ImplT>::type1>::value , 
                                         typename Foo_Traits<ImplT>::type2,
                                         T1>::type; 
};

疑似コードで書かれているようなものを実際に達成するにはどうすればよいですか

 using T2 = etc...
4

1 に答える 1

3

あなたの答えは、提案するN3911void_tにあります。

与えられた:

template <typename...>
using void_t = void;

has_type2_member次のように述語を記述できます。

template <typename, typename = void>
struct has_type2_member : std::false_type {};

template <typename T>
struct has_type2_member<T, void_t<typename T::type2>> : std::true_type {};

この述語を直接使用することはできませんが、必要に応じて変更できます。

template <typename ImplT>
class FooBase
{
  using T1 = typename Foo_Traits<ImplT>::type1;

  template <typename, typename = void>
  struct type2_or_type1 {
    using type = T1;
  };

  template <typename T>
  struct type2_or_type1<T, void_t<typename T::type2>> {
    using type = typename T::type2;
  };

  using T2 = typename type2_or_type1<Foo_Traits<ImplT>>::type;
};
于 2015-03-07T08:05:49.257 に答える