可能有尾随返回类型的条件重载?

时间:2012-08-08 14:07:50

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

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

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

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

我对使用预处理器的解决方案不感兴趣。我总是可以做像

这样的事情
#define RET(t) --> decltype(t) { return t; }

并扩展它以采取整个条件。相反,我感兴趣的是语言是否支持它而不使用返回类型的其他特征,即ReturnType<A,B>::type_t或函数体中使用的任何特征。

2 个答案:

答案 0 :(得分:9)

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())
{
  // ...
}

答案 1 :(得分: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的新功能之一。