如何实现将参数包传递到函数(栏)的函数(foo),该函数最终将参数包传递给类构造函数? 这是代码:
template <typename... Args>
void bar(Args&&... args)
{
MyObj obj(std::forward<Args>(args)...);
/* Do something with obj */
}
我是否必须将foo实现为
template <typename... Args>
void foo(Args&&... args)
{ bar(args...); }
或
template <typename... Args>
void foo(Args&&... args)
{ bar(std::forward<Args>(args)...); }
答案 0 :(得分:2)
您需要使用forward
。 forward
看起来像这样:
template <class T>
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
(forward
的另一个重载,但在这里无关紧要。)
对于模板参数包Arg
的每个元素Args
,Arg
可以是:(T
是非引用类型)
T&
,如果参数是非常量左值,则参数的类型为T&
;或
const T&
(如果参数是const左值),则参数的类型为const T&
;或
T
(如果参数是右值),则参数的类型为T&&
。
在第一种情况下,forward<Arg>(arg)
实例化为:
constexpr T& forward(T& t) noexcept
{
return static_cast<T&>(t);
}
导致要传递的非常量左值。
在第二种情况下,forward<Arg>(arg)
实例化为:
constexpr const T& forward(const T& t) noexcept
{
return static_cast<const T&>(t);
}
产生要传递的const左值。
在最后一种情况下,forward<Arg>(arg)
实例化为:
constexpr T&& forward(T&& t) noexcept
{
return static_cast<T&&>(t);
}
导致要传递的右值。
在所有这三种情况下,值类别都会保留,并且值会在修改为bar
的情况下转发。
如果您不使用forward
,则将无条件传递不需要的左值。