#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(使用前将#替换为@)