SFINAE与C ++ 14返回类型的扣除 [英] SFINAE with C++14 return type deduction

查看:141
本文介绍了SFINAE与C ++ 14返回类型的扣除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢C ++ 14,我们很快就能够缩减冗长的尾随返回类型;例如来自David Abrahams 2011的一个 min 示例 post

 code> 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 可以写为:

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

这是一个简单的例子,但是返回类型的扣除对通用代码非常有用,多复制。我的问题是,对于这样的功能,我们如何整合SFINAE技术?例如,如何使用 std :: enable_if 限制我们的 min 函数返回整数的类型? / p>

解决方案

如果使用返回类型扣除,你不能使用返回类型SFINAE函数。这在提案中已提及


由于通过实例化模板来推导返回类型,如果实例化不成功,则会导致错误,而不是替换失败。


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

 模板< 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& &
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 {}); //错误 - 无匹配函数min2
min2(10,20);

rel =nofollow>现场演示


Thanks to C++14, we'll soon be able to curtail verbose trailing return types; such as the generic min example from David Abrahams 2011 post:

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

Under C++14 the return type can be omitted, and min can be written as:

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

This is a simple example, however return type deduction is very useful for generic code, and can avoid much replication. My question is, for functions such as this, how do we integrate SFINAE techniques? For example, how can I use std::enable_if to restrict our min function to return types which are integral?

解决方案

You can't SFINAE the function using the return type if you're using return type deduction. This is mentioned in the proposal

Since the return type is deduced by instantiating the template, if the instantiation is ill-formed, this causes an error rather than a substitution failure.

You can, however, use an extra, unused template parameter to perform 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

这篇关于SFINAE与C ++ 14返回类型的扣除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆