该函数是否为完美转发函数?临时T的创建是否使其失去完美性?
问题解答
1. 该函数算不算完美转发函数?
- 得拆分来看:
foo对参数args的传递是符合完美转发要求的——它用std::forward<Args>(args)...把每个参数的原始值类别(左值/右值)完整传给了T的构造函数,这一步没毛病。 - 但要注意:完美转发的终点是
T的构造,不是传给bar的临时对象。传给bar的是个右值(临时T实例),不管原来的参数是左值还是右值,到这一步都变成了T的右值,所以从foo到bar的环节,不存在对原始参数的完美转发——我们转发的是构造T的参数,不是直接把原始参数转给bar。
2. 临时T对象的创建会不会破坏完美转发?
- 不会破坏对
args的完美转发:std::forward依然正确保留了每个args的值类别,让T的构造函数能匹配最合适的重载(比如左值引用构造、右值引用构造)。 - 但如果你的预期是把原始
args直接完美转发给bar,那这个写法确实做不到——中间多了T的构造,bar接收的是T对象,不是原始的args参数。
3. 关于开销的疑问
- 创建临时
T对象本身确实会有构造(可能还有析构)开销,但T是平凡类的话:- 编译器的**返回值优化(RVO)或临时对象省略(NRVO)**大概率会把
T的构造直接合并到bar的参数传递里,消除临时对象的开销。 - 平凡类的构造/析构本身就是极轻量的操作,就算没优化,开销也几乎可以忽略。
- 编译器的**返回值优化(RVO)或临时对象省略(NRVO)**大概率会把
- 完美转发说的“无开销”是指不会因为转发操作额外引入不必要的拷贝或转换,不是消除所有必要的对象构造——这里
T的构造是业务逻辑需要的步骤,不属于转发带来的额外开销。
内容的提问来源于stack exchange,提问作者user23339093
相关产品推荐
相关产品推荐

