我试图编写一个编译时泛型示例。我已经强制执行方法存在,但我无法弄清楚如何强制执行返回类型:
#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()
方法,但返回类型完全是任意的。我该如何强制执行此操作?
答案 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 {};