1

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

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或函数体中使用的任何特征。

4

2 回答 2

10

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

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

template<class T>
static auto hope(T const& arg)
  -> decltype(arg.foo(), void())
{
  // ...
}
于 2012-08-08T14:25:44.153 回答
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 新特性之一。

于 2012-08-08T15:03:16.163 回答