xerion
xerion

Reputation: 303

SFINAE to set alias template

I was wondering if it is possible to use SFINAE to set an alias template in a different class depending on the existence or not of an alias in a traits class.

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

Essentially we have 2 classes Foo1 and Foo2 and their traits class that define type aliases in this case to simplify it. In all cases we will have type1 alias and in some cases we will have a type2.

In a different class (in my cases it is actually the base class of Foo) I want to set aliases for these types.

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

How can I actually achieve something of the sort that is written in pseudocode over at

 using T2 = etc...

Upvotes: 1

Views: 363

Answers (1)

mpark
mpark

Reputation: 7904

Your answer can be found in N3911 that proposes void_t.

Given:

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

You can write your has_type2_member predicate like so:

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

We can't use this predicate directly, but we can modify it to our needs.

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

Upvotes: 3

Related Questions