【问题标题】:Ensure return type of templated generic parameter确保模板化泛型参数的返回类型
【发布时间】:2015-10-02 18:27:26
【问题描述】:

我正在尝试制作一个编译时泛型示例。我已经强制要求方法存在,但我不知道如何强制返回类型:

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

【问题讨论】:

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


    【解决方案1】:

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

    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

    【讨论】:

    • @Czipperz 您可以通过使用std::is_void 代替std::is_same&lt;..., void&gt; 来缩短语法
    • 不错。请注意,这也适用于没有 void_t:coliru.stacked-crooked.com/a/bd41f8a2c7b4bea2
    • @VaughnCato 是迂腐的,你应该使用std::enable_if&lt;..., void_t&lt;&gt;&gt;::type(以防void_t&lt;&gt;不是void,并且主模板采用class = void_t&lt;&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 2019-08-19
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多