确保模板化通用参数的返回类型

时间:2015-10-02 05:43:12

标签: c++ templates c++11 sfinae

我试图编写一个编译时泛型示例。我已经强制执行方法存在,但我无法弄清楚如何强制执行返回类型:

#include <type_traits>
template<class...> struct voider { using type = void; }
template<class... T> using void_t = typename voider<T...>::type;

template<class T, class = void> struct add_able : std::false_type {};
template<class T> struct add_able
< T, void_t < std::is_same < decltype(std::declval<T>().addOne()), void >,
              std::is_same < decltype(std::declval<T>().subOne()), void > > >
: std::true_type {};

class A { public: int addOne(); void subOne(); } // compiles and runs
class B { public: void addOne(int); void subOne(); } // fails
class C { public: void addOne(); void subOne(); } // compiles and runs as expected
class D { public: void subOne(); } // fails

这确保了addOne()subOne()方法,但返回类型完全是任意的。我该如何强制执行此操作?

1 个答案:

答案 0 :(得分:3)

std::is_same<T>是一种类型。它的实例化永远不会失败(触发替换失败),正如您所期望的那样。您必须将其包装在std::enable_if中,并通过访问嵌套的std::is_same<T>静态成员来读取::value返回的值。

template<class T, class = void> struct add_able : std::false_type {};
template<class T> struct add_able
< T, void_t < typename std::enable_if<
//                     ~~~~~~~~~~~~~^
           std::is_same < decltype(std::declval<T&>().addOne()), void >::value
//                                                                     ~~~~~~^
           && std::is_same < decltype(std::declval<T&>().subOne()), void >::value
//        ~^^~                                                            ~~~~~~^
              >::type
//             ~~~~~^
            >
>
: std::true_type {};

DEMO