将参数包传递给另一个可变参数模板函数时是否必须使用 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)...); }

您需要使用forwardforward 看起来像这样:

template <class T>
constexpr T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
    return static_cast<T&&>(t);
}

forward还有一个重载,但这里无关紧要。)

对于模板参数包Args的每个元素ArgArg可以是:(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,您将无条件地传递一个左值,这是不希望的。