将参数包传递给另一个可变参数模板函数时是否必须使用 std::forward
Do I have to use std::forward when passing arguments pack to another variadic template function
如何实现将参数包传递给函数 (bar) 的函数 (foo),函数 (bar) 最后将该参数包传递给 class 构造函数?
这是代码:
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)...); }
您需要使用forward
。 forward
看起来像这样:
template <class T>
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
(forward
还有一个重载,但这里无关紧要。)
对于模板参数包Args
的每个元素Arg
,Arg
可以是:(T
是一个non-reference类型)
T&
如果参数是 non-const 左值,那么参数的类型是 T&
;或
const T&
如果参数是一个 const 左值,那么参数的类型是 const T&
;或
T
如果参数是右值,那么参数的类型是 T&&
.
在第一种情况下,forward<Arg>(arg)
实例化为:
constexpr T& forward(T& t) noexcept
{
return static_cast<T&>(t);
}
导致要传递 non-const 左值。
在第二种情况下,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
,您将无条件地传递一个左值,这是不希望的。
如何实现将参数包传递给函数 (bar) 的函数 (foo),函数 (bar) 最后将该参数包传递给 class 构造函数? 这是代码:
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)...); }
您需要使用forward
。 forward
看起来像这样:
template <class T>
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
(forward
还有一个重载,但这里无关紧要。)
对于模板参数包Args
的每个元素Arg
,Arg
可以是:(T
是一个non-reference类型)
T&
如果参数是 non-const 左值,那么参数的类型是T&
;或const T&
如果参数是一个 const 左值,那么参数的类型是const T&
;或T
如果参数是右值,那么参数的类型是T&&
.
在第一种情况下,forward<Arg>(arg)
实例化为:
constexpr T& forward(T& t) noexcept
{
return static_cast<T&>(t);
}
导致要传递 non-const 左值。
在第二种情况下,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
,您将无条件地传递一个左值,这是不希望的。