为啥 const 模板参数不是通用/转发参考
Posted
技术标签:
【中文标题】为啥 const 模板参数不是通用/转发参考【英文标题】:Why is const template parameter not a universal/forwarding reference为什么 const 模板参数不是通用/转发参考 【发布时间】:2020-12-13 14:47:01 【问题描述】:我正在阅读有关通用参考/转发参考和this link says 的内容:
这里的param
是通用参考:
template<typename T>
void f(T&& param);
但是这里param
不是一个通用引用,它是一个右值引用:
template<typename T>
void f(const T&& param);
通用引用的定义如下:
如果一个变量或参数被声明为 T&& 对于某个推导出的类型 T,则该变量或参数是一个通用引用。
我读到 T 是一个推导类型,因为 Template argument deduction。
为什么第二种情况不是通用参考?出于某种原因,const T&& param
的存在是否不遵循模板参数推导?如果有,为什么?
【问题讨论】:
【参考方案1】:前言:官方术语是转发引用。
那么为什么第二种情况不是通用参考呢?
因为它是对 const 的引用。并且对 const 的引用不是转发引用。
为什么?
转发引用的全部意义在于,当将右值作为参数给出时,该参数将被推断为对非常量右值的引用,这允许在转发时移动此类参数(同时允许左值不被移出)。您不能从对 const 的引用移动,因为移动构造函数的参数将是对非 const 的右值引用,它不能绑定到对 const 的引用。
语言律师的回答是:因为标准是这样说的:
[temp.deduct.call] 转发引用是对 cv-unqualified 模板参数的右值引用,它不代表类模板的模板参数...
【讨论】:
【参考方案2】:因为它会破坏目的。
即使它是转发引用,在传入右值时也会得到 const 右值引用。移动语义需要非 const 引用,以便可以修改源对象,因为关键在于窃取即将过期的对象,而不是做一个可能很昂贵的副本。
无论价值类别如何,您都会一直进行复制。所以在这种情况下“转发”没有意义。
【讨论】:
以上是关于为啥 const 模板参数不是通用/转发参考的主要内容,如果未能解决你的问题,请参考以下文章
显式指定通用 lambda 的 operator() 模板参数是不是合法?