C++ 转发非右值引用的可变参数值

C++ Forwarding on variadic values which are not rvalue references

考虑:

template <typename... Args>
void foo(Args... args) {
    bar(std::forward<Args>(args)...);
}

template <typename... Args>
void foo2(Args&&... args) {
    bar(std::forward<Args>(args)...);
}

我理解在 foo2 的情况下完美的右值引用转发,但是转发 foo 的可变参数值的目的是什么?

如果 foo 看起来像这样会有什么不同?

template <typename... Args>
void foo(Args... args) {
    bar(args...);
}

这不是一回事。

在这个

template <typename... Args>
void foo(Args... args) {
    bar(std::forward<Args>(args)...);
}
  • Args 永远不会被推断为引用(foo(Args...) 意味着 foo 按值而不是引用来获取参数);
  • 另一方面std::forward<T>(t) is nothing more than static_cast<T&&>(t), just with a more explicit intent from the programmer;

这两件事加起来就是 static_cast<Args&&>(args)... 有一个右值引用 return 类型,即 returning 一个右值(因为 Args 不是引用,所以Args&& 之间不会发生引用折叠以提供左值引用 return 类型,这意味着左值 return 值)。

所以不,在您的第一个版本 foo 中没有完美的转发。其中的 std::forward 无条件地将其参数转换为右值;这通常是 std::move 的工作:

// this is equivalent to the code above
template <typename... Args>
void foo(Args... args) {
    bar(std::move(args)...);
}