SFINAE与C++ 14返回类型扣除

use*_*370 7 c++ templates sfinae c++14

感谢C++ 14,我们很快就能够减少冗长的尾随返回类型; 例如minDavid Abrahams 2011 帖子的一般例子:

template <typename T, typename U>
auto min(T x, U y)
    -> typename std::remove_reference< decltype(x < y ? x : y) >::type
{ return x < y ? x : y; }
Run Code Online (Sandbox Code Playgroud)

在C++ 14下,返回类型可以省略,min可以写成:

template <typename T, typename U>
auto min(T x, U y)
{ return x < y ? x : y; }
Run Code Online (Sandbox Code Playgroud)

这是一个简单的示例,但是返回类型推导对于通用代码非常有用,并且可以避免很多复制.我的问题是,对于这样的功能,我们如何整合SFINAE技术?例如,我如何使用std::enable_if限制min函数返回积分类型?

Pra*_*ian 12

如果您使用返回类型扣除,则不能使用返回类型SFINAE函数.提案中提到了这一点

由于返回类型是通过实例化模板推断出来的,如果实例化不正确,则会导致错误而不是替换失败.

但是,您可以使用额外的未使用模板参数来执行SFINAE.

template <class T, class U>
auto min1(T x, U y)
{ return x < y ? x : y; }

template <class T, class U,
          class...,
          class = std::enable_if_t<std::is_integral<T>::value &&
                                   std::is_integral<U>::value>>
auto min2(T x, U y)
{
    return x < y ? x : y; 
}

struct foo {};

min1(foo{}, foo{}); // error - invalid operands to <
min1(10, 20);

min2(foo{}, foo{}); // error - no matching function min2
min2(10, 20);
Run Code Online (Sandbox Code Playgroud)

现场演示

  • +1你甚至可以使用`std :: enable_if_t`助手模板. (2认同)
  • @ user2023370不幸的是,这是你的退货类型扣除.对于面向用户的函数,我更喜欢SFINAE在返回类型上使用未使用的参数,这样他们就不必挖掘`decltype`或`enable_if`表达式来确定类型是什么,但是你可以认为这就是文档的用途.无论如何,有人提供明确的第三个模板参数的解决方案...更多未使用的参数:)请参阅更新的答案; 添加参数包后,您将无法为执行SFINAE的参数提供参数. (2认同)