C++ 带C+的SFINAE+;14返回类型扣除
多亏了C++14,我们很快就能减少冗长的尾随返回类型;例如David Abrahams 2011的通用C++ 带C+的SFINAE+;14返回类型扣除,c++,templates,sfinae,c++14,C++,Templates,Sfinae,C++14,多亏了C++14,我们很快就能减少冗长的尾随返回类型;例如David Abrahams 2011的通用min示例: 这是一个简单的示例,但是返回类型推断对于泛型代码非常有用,可以避免大量复制。我的问题是,对于这样的功能,我们如何集成SFINAE技术?例如,如何使用std::enable_if将min函数限制为整数返回类型?如果使用返回类型推断,则无法使用返回类型定义函数。报告中提到了这一点 由于返回类型是通过实例化模板推导出来的,因此如果实例化格式不正确,则会导致错误,而不是替换失败 但是,您可
min
示例:
这是一个简单的示例,但是返回类型推断对于泛型代码非常有用,可以避免大量复制。我的问题是,对于这样的功能,我们如何集成SFINAE技术?例如,如何使用
std::enable_if
将min
函数限制为整数返回类型?如果使用返回类型推断,则无法使用返回类型定义函数。报告中提到了这一点
由于返回类型是通过实例化模板推导出来的,因此如果实例化格式不正确,则会导致错误,而不是替换失败
但是,您可以使用一个额外的、未使用的模板参数来执行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);
模板
自动最小1(T x,U y)
{返回x
更不用说
std::is_integal_v
@0x499602D2 gcc-4.9的libstdc++具有启用功能,如果它
。我现在肯定会更频繁地使用它。对于gcc-4.8,我从未使用过它,因为我不想在clang和gcc之间过多地更改coliru的命令行:)@chris我无法获得::value
的帮助程序模板来使用gcc或clang处理coliru。我知道SFINAE的这种用法,我的建议是,返回类型将形成SFINAE条件,而不是参数:对于内置类型,返回类型将是其中一个参数的类型,但对于用户类型则不是。我也只是以min
为例。似乎很不幸,推断出的返回类型注定无法被我们理解。我相信我们还没有看到尾部返回decltype代码复制的结束。@user2023370不幸的是,这是返回类型推断的结果。对于面向用户的函数,我更喜欢带有未使用参数的SFINAE而不是返回类型,这样它们就不必通过decltype
或enable\u if
表达式来找出类型,但您可以说这就是文档的目的。无论如何,有一个解决方案可以帮助提供显式第三个模板参数的人。。。更多未使用的参数:)请参阅更新的答案;添加参数包后,您将无法为执行SFINAE的参数提供参数。
template <typename T, typename U>
auto min(T x, U y)
{ return x < y ? x : y; }
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);