我不明白这段代码是如何工作的。有人能给我一点启发吗。我很确定“参数包应该是最后一个参数”
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);
}如果允许的话,我如何分割arg1、args2和args3?
编译器(g++-11)假定除args3之外的所有参数包都是空的,因此输出是
args1:
args2:
args3:
1 2 3 4 5 6发布于 2022-10-28 13:28:23
这个程序是格式不良的,gcc和clang在接受代码方面是错误的.您也可以通过稍微修改代码来确认这一点,如下所示。这里也有一个旧的gcc虫。
基本上,在函数模板(在下面所示的修改程序中)允许多个模板参数包的情况下,只要在模板参数包后面的每个模板参数都有一个默认值,或者可以推导它。但是,由于T2和T3都不满足这些需求(因为它们不能明确推导并且不能具有默认参数),所以程序的格式是错误的。
同样的推理也适用于给定的示例,因为foo(在原始示例中)是一个泛型函数(也称为缩写函数模板)。
GCC和Clang对以下修改程序显示了相同的错误行为:演示
template<typename... T1, typename... T2, typename... T3>
void foo(T1&&...args1, T2&&... args2, T3&&... 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); //gcc and clang compiles this while msvc correctly rejects this
}下面是gcc的错误:
下面是clang bug:
从temp.param也可以看到同样的情况。
函数模板的模板参数包不应后面跟着另一个模板参数,除非该模板参数可以从函数模板的参数类型列表(dcl.fct)中推导出来,或者具有默认参数 (temp.deduct)。 // U既不能从参数类型列表中推导,也不能从指定的template void (){} // error
(强调地雷)
发布于 2022-10-28 10:10:01
如果允许的话,我如何分割arg1、args2和args3?
您不能。您可以使用std::tuple将模板包收集到一个参数中。
template <typename... Args1, typename... Args2, typename... Args3>
void foo(std::tuple<Args1...> args1, std::tuple<Args2...> args2, std::tuple<Args3...> args3) {
    auto out = []<std::size_t... Is>(std::string name, auto tup, std::index_sequence<Is...>)
    {
        std::cout << name << " ";
        ((std::cout << get<Is>(tup) << " "), ...);
        std::cout << std::endl;
    };
    
    out("args1", args1, std::index_sequence_for<Args1...>{});
    out("args2", args2, std::index_sequence_for<Args2...>{});
    out("args3", args3, std::index_sequence_for<Args3...>{});
}发布于 2022-10-29 15:26:00
我在“拥抱现代C++安全”一书中写了一章,并在https://www.youtube.com/watch?v=va9I2qivBOA的演讲中讨论了这一点和相关问题。
https://stackoverflow.com/questions/74233537
复制相似问题