这是一个完美的转发功能吗?或者临时T的创建是否会使其变得不完美? T 是一个简单的类。
template<class T, typename... Args>
void foo(Args&&... args)
{
bar(T{std::forward<Args>(args)...});
}
如果它是一个完美的转发函数,我希望它不会产生任何开销,但创建 T 必须产生开销,除非编译器可以进行合适的优化。
完美转发并不意味着没有开销,在当前的 C++ 中,完美转发总是有可能创建不需要的临时对象。例如:
class C { C(int); };
void foo(C c);
template <class Arg>
void bar(Arg&& arg) {
foo(std::forward<Arg>(arg));
}
C getC();
int main() {
foo(getC());
bar(getC());
}
在调用
foo(getC())
中,会发生保证的复制省略,并且 getC
中的 return 语句将 C
对象直接构造到 c
的参数 foo
中,而不会发生任何复制或移动。在使用完美转发的调用bar(getC())
中,首先具体化纯右值getC()
,以便绑定到bar
的引用参数,然后调用C
的移动构造函数来初始化 c
来自 std::forward<Arg>(arg)
。
你可能会说完美转发并不完美。
无论如何,“完美转发”的意思是,左值作为相同类型的左值转发,右值作为相同类型的右值转发。在原始示例中,传递给
foo
的左值作为相同类型的左值转发给 T
的构造函数,传递给 foo
的右值作为相同类型的右值转发给 T
的构造函数。所以是的,您在这里拥有完美的转发。