确保 return 类型的模板化泛型参数

Ensure return type of templated generic parameter

我正在尝试制作一个编译时泛型示例。我已经强制执行这些方法存在,但我不知道如何强制执行 return 类型:

#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() 方法,但 return 类型是完全任意的。我该如何执行?

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

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