相关疑难解决方法(0)

具有多个可变参数的函数是什么?

我不明白这段代码是如何工作的。谁能告诉我一点。我非常确定“参数包应该是最后一个参数”

void foo(auto&&...args1, auto&&... args2, auto&&... args3) {
    std::cout << "args1:\n", ((std::cout << args1 << " "), ...);
    std::cout << "args2:\n", ((std::cout << args2 << " "), ...);
    std::cout << "args3:\n", ((std::cout << args3 << " "), ...);
}

int main(int argc, char** argv)
{
    foo(1,2,3,4,5,6);
}
Run Code Online (Sandbox Code Playgroud)

如果允许,我如何拆分arg1、args2和args3?

编译器 (g++-11) 假定除 args3 之外的所有参数包均为空,因此输出为

args1:
args2:
args3:
1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)

c++ c++20

11
推荐指数
1
解决办法
505
查看次数

具有两个参数包的函数模板重载决策

请考虑以下代码:

#include<iostream>

template<class..., class... T>
int f(T...) { return 1; }

template<class... T>
int f(T...) { return 2; }

int main()
{
    std::cout << f(1);
}
Run Code Online (Sandbox Code Playgroud)

1在gcc 8.2上编译和打印,但由于调用f(1)不明确而无法在clang 7上编译.

如果调用被替换为f()两个编译器都无法编译声称调用是不明确的.

如果参数包class... T被以简单的参数替换class T(和T...T),二者编译器也要求歧义.

在第一个示例中,哪个编译器符合标准?我想这归结为功能模板的特定部分排序规则,还是以这种方式使用双参数包已经形成错误了?

编辑:

我的理解是双包本身并不是格式错误,因为我的阅读中的[temp.param] 17.1/15似乎明确允许这个,如果第二个包可以从函数参数中推导出来,这似乎是因为该T...函数参数包.

也可以显式指定第一个参数包的参数,但不是第二个参数包的参数,因此并不总是(在模板参数推断之后)至少一个参数包为空.我不确定这是否会使程序格式不正确,因为我不知道在这种情况下如何阅读例如[temp.res] 17.7/8.3.

gcc和clang似乎都没有双参数包本身,例如当第二个函数模板重载被删除时,两个编译器都打印1.但这可能是形成不良的情况,无需诊断.

此外,我假设使用类模板参数推导,可变参数类模板可以定义一个可变参数构造函数模板,这意味着构造函数候选类似于我的双参数包示例,据我所知,相同的重载决议和模板参数推导需要在这种情况下.这个问题是由另一个带有这样设置的问题所驱动的:Variadic类模板推导失败,使用gcc 8.2,编译clang和msvc 另请参阅讨论:使用可变参数模板构造函数的演绎指南和可变参数类模板 - 不匹配的参数包长度

现在我也找到了问题的演绎指南和可变参数模板的答案,我假设gcc是错误的并且调用应该被认为是模棱两可的,但我想让它验证这适用于这里同样的方式.我也会更加详细地欢迎推理,因为功能模板偏序规则对我来说似乎很不清楚.

c++ language-lawyer overload-resolution template-argument-deduction

9
推荐指数
1
解决办法
210
查看次数