用`std :: enable_if`和非推导上下文重载函数模板

罗密欧

考虑以下代码:

template <typename T>
struct dependent_type
{
    using type = T;
};

template <typename T>
auto foo(T) -> std::enable_if_t<std::is_same<T, int>{}>
{
    std::cout << "a\n"; 
}

template<typename T> 
void foo(typename dependent_type<T>::type) 
{
    std::cout << "b\n";
}
  • foocan的第一个重载可以T从其调用中得出。

  • 的第二过载foo是一个非推测的上下文

int main()
{    
    foo<int>( 1 );      // prints "b"
    foo<double>( 1.0 ); // prints "b"
    foo( 1 );           // prints "a"
}

为什么foo<int>( 1 )打印“ b”而不打印“ a”?

魔盒示例

格子呢骆驼

本质上,部分排序规则说,dependent_type由于该非推论上下文重载更加专业化。

模板功能排序的过程基于变换模板功能类型并依次对每种模板执行模板推演,一次是从第一个模板(一个拿走T)到第二个模板(一个拿走dependent_type),然后是从第二个到第一个。

这些规则太过复杂而无法在此处复制,但是[temp.func.order]如果您需要血腥的细节,请阅读阅读其链接的段落。这是一个快速的简化:

对于模板函数的每个模板参数,组成一个唯一的类型,然后用该类型替换参数。此示例的转换类型为:

void foo(UniqueType); //ignoring the SFINAE for simplicity
void foo(typename dependent_type<UniqueType>::type); 

然后,我们在两个方向上执行模板推导:一次使用第一个模板的参数作为第二个模板的参数,一次使用第二个模板的参数作为第一个模板的参数。这类似于对以下函数调用执行推导:

//performed against template <class T> void foo(typename dependent_type<T>::type);
foo(UniqueType{});                     

//performed against template <class T> void foo(T);        
foo(dependent_type<UniqueType>::type{});

在进行这些推论时,我们试图辨别一个过载是否比另一个过载更专业。当我们尝试第一个时,推论失败,因为这typename dependent_type<T>::type是一个非推论的上下文。对于第二个,推论成功是因为dependent_type<UniqueType>::type公正UniqueType,所以T推论到UniqueType

由于推论从第二个模板到第一个模板失败,因此第二个模板被认为比第一个模板更专业。最终结果是,重载分辨率优先选择的第二个模板foo<int>(1)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std::enable_if 与非直接上下文中的硬错误

带有 std::enable_if 和 std::decay 的 C++ 类构造函数模板

模板参数推导和SFINAE-使用std :: enable_if

使用std :: initializer_list参数的非成员函数(/非构造函数上下文)的重载解析

使用 std::enable_if 重载函数以避免模板替换错误

用std :: async调用模板成员函数

具有std :: enable_if的C ++可变参数模板部分模板专业化

可变参数模板专门化,std :: enable_if,SFINEE

用`std :: function`和先前推导出的模板参数替换失败-为什么?

可以使用 std 容器为函数模板推导出类型参数吗?

将std :: enable_if与离线成员函数和模板化静态成员条件一起使用

同时接受std :: vector和QVector的函数模板?

用`std :: wostream`和`std :: string`重载ʻoperator <<`时出现“ no match”和“ cannot bind lvalue”错误

用混合的const和非const元素模拟std :: vector

如何更换的std :: ptr_fun用的std ::功能和std :: REF

基于可变模板存在的std :: enable_if

std :: complex的模板函数重载

使用std :: enable_if和std :: is_arithmetic作为模板参数的问题

如何使用 std::enable_if 元函数实现类模板函数?

用基数排序实现std :: sort的重载合法吗?

用默认参数推导可变参数模板参数

用泛型反应上下文

用Json反应上下文Api

std :: enable_if如果参数是函数?

SFINAE:std :: enable_if作为函数参数

使用std :: enable_if的带有模板重载的隐式转换运算符T()无法编译

如何在 std::enable_if 的帮助下定义模板函数

如何根据模板类型使用std :: enable_if启用或禁用构造函数?

在模板函数返回类型上使用std :: enable_if以利用SFINAE-编译错误