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

时间:2014-06-24 21:41:29

标签: c++ templates sfinae c++14

感谢C ++ 14,我们很快就可以减少详细的尾随返回类型;例如David Abrahams 2011 post中的通用min示例:

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; }

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

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

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

1 个答案:

答案 0 :(得分:12)

如果您使用返回类型扣除,则不能使用返回类型SFINAE函数。这在proposal

中提到
  

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

但是,您可以使用额外的未使用模板参数来执行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);

Live demo