【问题标题】:Conditional overloading with trailing-return-type possible?可以使用尾随返回类型进行条件重载吗?
【发布时间】:2012-08-08 14:07:49
【问题描述】:

假设您尝试执行以下操作:

template</* args */>
typename std::enable_if< /*conditional*/ , /*type*/ >::type
static auto hope( /*args*/) -> decltype( /*return expr*/ )
{
}

是否可以将条件包含/重载 (std::enable_if) 与尾随返回类型 (auto ... -&gt; decltype()) 结合起来?

我不会对使用预处理器的解决方案感兴趣。我总是可以做类似的事情

#define RET(t) --> decltype(t) { return t; }

并将其扩展为也采用整个条件。相反,如果语言支持它而不使用返回类型的另一个特征,即ReturnType&lt;A,B&gt;::type_t 或函数体中使用的任何内容,我感兴趣。

【问题讨论】:

    标签: c++ templates c++11 sfinae trailing-return-type


    【解决方案1】:

    trailing-return-type 与普通返回类型没有太大区别,只是它是在参数列表和 cv-/ref-qualifiers 之后指定的。另外,它不一定需要decltype,普通类型也可以:

    auto answer() -> int{ return 42; }
    

    所以现在你应该看到你的问题的答案是什么了:

    template<class T>
    using Apply = typename T::type; // I don't like to spell this out
    
    template</* args */>
    static auto hope( /*args*/)
        -> Apply<std::enable_if</* condition */, decltype( /*return expr*/ )>>
    {
    }
    

    虽然我个人更喜欢只使用 decltype 和表达式 SFINAE,但只要条件可以表示为表达式(例如,您可以在特定类型的对象上调用函数):

    template<class T>
    static auto hope(T const& arg)
      -> decltype(arg.foo(), void())
    {
      // ...
    }
    

    【讨论】:

    • 太棒了!谢谢!所以,你的第二种情况不支持条件std::is_base_of&lt;&gt;::value,对吧?在这种情况下,我们会选择第一种情况。
    • @Frank:是的,is_base_of 很容易测试。您可以轻松检查某个类型是否可转换为另一种类型(decltype(T2(obj_of_T1)) 用于显式转换),但您无法确定该类是否只有转换运算符/ctor 或者它是否是基类,这需要一些额外的黑盒魔术(或编译器支持)。
    • 嗯...懒得查了,但我认为你不能在非模板函数上使用enable_if(即使它是模板的成员)。
    • @David:是的,我会添加它并将模板标签添加到问题中;毕竟,SFINAE 永远不会没有模板。
    【解决方案2】:

    我只能假设您的原始伪代码是一个函数模板,否则 SFINAE 将无法完全工作。现在,如果它是一个模板函数,您可以使用一个默认的额外模板参数并在该参数上使用 SFINAE:

    template <typename T, typename _ = typename std::enable_if< trait<T>::value >::type >
    static auto function( T arg ) -> decltype( expression ) {
       // ...
    }
    

    我更喜欢这个,因为它将 SFINAE 的使用限制在 template 子句中,并留下更清晰的函数签名。这是我最喜欢不为人知的 C++11 的新特性之一。

    【讨论】:

    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 2017-01-25
    • 2020-06-13
    相关资源
    最近更新 更多