C++11 标准:前进<;Args>;或标准::转发<;参数…>;?

C++11 标准:前进<;Args>;或标准::转发<;参数…>;?,c++11,variadic-templates,C++11,Variadic Templates,我遇到了两种使用可变模板参数的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

我遇到了两种使用可变模板参数的
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

}
模板
void foo(Args&…arga)
{
条(std::forward(args);//变量1
条(std::forward(args);//变量2
//以上编辑是固定版本,初始版本不正确
//条(std::forward(args…);//变量1
//条(std::forward(args…);//变量2
}
我用g++和clang尝试了这两种变体,它们似乎都工作得同样好。使用
-Wall-Wextra-Wpedantic
不会产生警告

两种变体都正确吗?若否,原因为何?标准对此有何解释?

bar(std::forward(args)…);//变式1
bar(std::forward<Args>(args)...);      // variant 1
这是正确的

bar(std::forward<Args...>(args...));   // variant 2
bar(std::forward(args…);//变式2
这是错误的

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

如果包有一个元素,两个变量都会扩展到
条(std::forward(t))
,这是有效的

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

因此,在所有情况下,变量1都是有效的,但变量2仅对包含一个元素的参数包有效(如果您只关心一个模板参数,则不应使用变量模板!)


基本上,包扩展应该是
PATTERN…
,其中PATTERN是您希望为包中的每个元素重复的内容。由于您希望为每个元素调用
std::forward(t)
,因此模式应为
std::forward(args)
,因此完整包扩展后紧跟
(模式中没有
,这会导致两个独立的包扩展,一个是
Args
中的类型,另一个是
Args
中的变量)。

很抱歉,省略号混淆了所有人。嗯,如果包是空的,第二个包不是扩展到
std::forward()
?@DanielFrey
std::forward(args).
扩展为空。
std::forward(args…
扩展为
std::forward()
@T.C.是的,你说得对,经过编辑——但格式仍然不正确。即使你更新的问题没有多大变化,变量2仍然不能使用两个或多个参数。你实际上是如何测试你的代码的?你需要看看它是否真的有效。@DanielFrey显然它没有得到充分的测试。