我正在编写包含其他库中的许多函数和方法的库。为了避免处理返回值,我这样应用std::forward
:
template<class T>
T&& wrapper(T&& t) {
f(t); // t passed as lvalue
return std::forward<T>(t);
}
f
返回void
和接受T&&
(或重载价值)。包装器始终返回包装器的参数,并且返回值应保留参数的价值。我真的需要使用std::forward
inreturn
吗?RVO 是否让它变得多余?它是参考(R 或 L)这一事实是否使它变得多余?如果 return 不是最后一个函数语句(在某些 if 中),是否需要它?
是否wrapper()
应该返回void
or是有争议的T&&
,因为调用者可以通过 arg 访问评估值(即引用,R 或 L)。但在我的情况下,我需要返回值,以便wrapper()
可以在表达式中使用。
这可能与问题无关,但众所周知,函数f
不会从 中窃取t
,因此第一次使用std::forward
inf(std::forward<T>(t))
是多余的,它被我删除了。
我写过小测试:https ://gist.github.com/3910503
测试表明,返回未转发的T
- 确实会在 gcc48 和 clang32 中使用 -O3 创建额外的副本(RVO 不会启动)。
此外,我无法从 UB 获得不良行为:
auto&& tmp = wrapper(42);
它不能证明任何原因,因为它是未定义的行为(如果它是 UB)。