C++未命名类型完美转发:两种参数传递写法是否始终等价?
for (auto&& elem : elems) { using E = decltype(elem); f(static_cast<E&&>(elem)); // 1 f(std::forward<E>(elem)); // 2 }
结论
以上两种写法始终完全等价,不存在任何行为差异,哪怕处理lambda这类未命名类型也适用。
原理说明
auto&& elem是转发引用,decltype(elem)推导得到的类型E规则固定:若elem绑定左值,E为左值引用类型;若elem绑定右值,E为右值引用类型。- C++标准明确规定
std::forward<T>(t)的底层实现本质就是static_cast<T&&>(t),两种写法都会触发引用折叠规则:- 当
E是左值引用T&时,E&&会折叠为T&,最终传给f的是左值 - 当
E是右值引用T&&时,E&&会折叠为T&&,最终传给f的是右值
- 当
- 未命名类型不会影响类型推导、引用折叠的规则逻辑,因此两类写法在所有场景下的运行效果完全一致。
- 两者仅存在可读性差异:
std::forward<E>(elem)的写法语义更清晰,直接标明代码的意图是做完美转发。
内容的提问来源于stack exchange,提问作者Zizheng Tai
相关产品推荐
相关产品推荐

