关于通用引用类型与std::forward参数值类别的困惑
解答《Effective Modern C++》中的看似矛盾表述
这两个表述并不矛盾,核心是要区分变量的静态类型和表达式的值类别这两个完全不同的概念:
1. Item 1 讲的是模板类型推导后的静态类型
当向f(T&& param)传入右值27时,模板推导规则会将T推导为int,因此param的静态类型是int&&(右值引用类型)。这是编译阶段确定的变量本身的类型,是Item 1要讲的类型推导结果。
2. Item 23 讲的是表达式的值类别
虽然param的静态类型是int&&,但在函数体内,param作为一个具名变量,它的表达式属性是左值——因为任何具名的变量(哪怕是右值引用类型),在被使用时都是左值(你可以对它取地址,比如¶m是合法的)。
举个代码例子直观理解:
template<typename T> void f(T&& param) { // param的静态类型是int&&(传入右值27时) int* addr = ¶m; // 合法,说明param是左值表达式 // 如果要把param还原为原来的右值属性,需要用std::forward auto&& original_rvalue = std::forward<T>(param); }
简单总结:
- Item 1关注的是「模板推导后param被声明成什么类型」
- Item 23关注的是「在函数里使用param这个表达式时,它的值类别是什么」
这两个描述针对的是C++类型系统的不同维度,完全不冲突。
内容的提问来源于stack exchange,提问作者Rogmier
相关产品推荐
相关产品推荐

