C++ 临时值的模板类型推导

2024-03-12

#include <iostream>
#include <vector>
using namespace std;

template <typename T>
void wrapper(T& u)
{
    g(u);
}

class A {};

void g(const A& a) {}
int main()
{
    const A ca;
    wrapper(ca);
    wrapper(A()); // Error
}

您好,我有一个问题,为什么最后一条语句会出现编译器错误。

:18:10: 错误:无法绑定类型的非常量左值引用 'A&' 到类型 'A' 的右值包装器(A());

我以为模板类型T将被推论为const A& as the ca也推导为const A&。为什么在这种情况下类型推导会失败?


我认为模板类型 T 将被推导为 const A&,因为 ca 也被推导为 const A&。为什么在这种情况下类型推导会失败?

因为这不是扣除规则的运作方式。他们努力推断尽可能多的与函数参数类型的匹配。临时变量不一定是 const,它可以只绑定到 const 引用。

但是您的函数模板不接受 const 引用,而是接受非 const 左值引用。所以不行const除非函数参数本身是 const(但事实并非如此),否则就会出现。

正确的解决方案是使用转发引用(对推导模板参数的右值引用):

template <typename T>
void wrapper(T&& u)
{
    g(std::forward<T>(u));
}

Now u可以绑定到任何对象。推导的类型将告诉您函数参数的值类别,允许您将该类别转发给函数调用g(...),并确保选择适当的过载。


顺便说一句,如果您好奇,如果您将 const 直接添加到临时类型,您的原始代码将构建得很好。

using CA = A const;
wrapper(CA()); // Not an error anymore

Now u最终成为A const&并绑定到临时就好了。但这只是一种好奇心,在实践中不太可能有用。使用转发参考。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 临时值的模板类型推导 的相关文章

随机推荐