Jae*_*bum 3 c++ templates function-templates type-deduction
#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
}
Run Code Online (Sandbox Code Playgroud)
嗨,我有一个问题,为什么最后一个语句给出编译器错误.
:18:10:错误:无法将类型为'A&'的非const左值引用绑定到类型'A'包装器(A())的右值;
我认为模板类型T将被推断为,const A&因为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));
}
Run Code Online (Sandbox Code Playgroud)
现在u可以绑定到任何对象.推导出的类型将告诉您函数参数的值类别,允许您将该类别转发给函数调用g(...),并确保选择正确的重载.
顺便说一句,如果你好奇,如果你将const直接添加到临时类型,你的原始代码将建立得很好.
using CA = A const;
wrapper(CA()); // Not an error anymore
Run Code Online (Sandbox Code Playgroud)
现在u最终成为一个A const&并且临时就好了.但这只是一种在实践中不太可能有用的好奇心.使用转发参考.
在这种情况下,为什么类型扣除失败?
它不会失败.T被推断为A.因此,参数u是类型A&.
调用wrapper()实际上是失败的,因为rvalue(即:A()在这种情况下)不能绑定到非const 左值引用(即:参数u).
| 归档时间: |
|
| 查看次数: |
200 次 |
| 最近记录: |