SFINAE设置别名模板

时间:2015-03-07 07:25:52

标签: c++11 sfinae template-aliases

我想知道是否可以使用SFINAE在不同的类中设置别名模板,具体取决于traits类中别名的存在与否。

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及其traits类,在这种情况下定义类型别名以简化它。 在所有情况下,我们都会有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...

1 个答案:

答案 0 :(得分:3)

您的回答可以在提出void_t的{​​{3}}中找到。

假设:

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