gpt4 book ai didi

c++11 - std::forward 还是 std::forward

转载 作者:行者123 更新时间:2023-12-01 07:18:40 30 4
gpt4 key购买 nike

我遇到了 std::forward 的两种变体与可变参数模板参数一起使用。

template <typename... Args>
void foo(Args&&... arga)
{
bar(std::forward<Args>(args)...); // variant 1
bar(std::forward<Args...>(args)...); // variant 2

// EDIT the above is a fixed version, the initial incorrect version was
// bar(std::forward<Args>(args...)); // variant 1
// bar(std::forward<Args...>(args...)); // variant 2

}

我已经用 g++ 和 clang 尝试了这两种变体,而且看起来都同样好用。 -Wall -Wextra -Wpedantic 没有产生警告.

两种变体都正确吗?如果不是,为什么不呢?标准对此有何规定?

最佳答案

bar(std::forward<Args>(args)...);      // variant 1

这是对的。
bar(std::forward<Args...>(args...));   // variant 2

这是错误的。

如果参数包为空,则变体 1 扩展为 bar()这是有效的,但变体 2 扩展为 bar(std::forward<>())这是格式错误的,因为 forward缺少它的参数。

如果包有一个元素,则两个变体都扩展为 bar(std::forward<T>(t))这是有效的。

如果包有两个元素,则变体 1 正确扩展为 bar(std::forward<T1>(t1), std::forward<T2>(t2))这是有效的。但是对于两个元素,变体 2 扩展为 bar(std::forward<T1, T2>(t1, t2))这是格式错误的,因为 std::forward有一个模板参数和一个函数参数。

因此,在所有情况下,变体 1 都有效,但变体 2 仅适用于具有一个元素的参数包的情况(如果您只关心单个模板参数,则根本不应该使用可变参数模板!)

基本上一个包扩展应该是 PATTERN...其中 pattern 是您希望为包中的每个元素重复的内容。既然你想调用 std::forward<T>(t)对于每个元素,PATTERN 应该是 std::forward<Args>(args)所以完整的包扩展是紧随其后的 ... (与 PATTERN 中的 ... 无关,这会导致两个单独的包扩展,其中一种是 Args 中的类型,一种是 args 中的变量)。

关于c++11 - std::forward<Args> 还是 std::forward<Args...>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27528352/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com