提问人:Crt 提问时间:9/25/2023 最后编辑:Jan SchultkeCrt 更新时间:9/25/2023 访问量:113
如何遍历可变参数列表 [duplicate]
How to loop through a list of variadic arguments [duplicate]
问:
当我尝试通过以下函数遍历可变参数时
我不明白'{(Print(Param),0)... }'其中使用 0
#include<iostream>
using namespace std;
template<typename T>
void Print(T& arg)
{
cout << arg << endl;
}
template<typename ...ParamTypes>
void Func(ParamTypes &...Param)
{
int arr[] = { (Print(Param),0)... };
}
int main()
{
int num = 10;
Func(num,num,num);
return 0;
}
当我不添加 0 时,它会给我一个错误
答:
1赞
YSC
9/25/2023
#1
就好像一个(模板)函数返回一样,需要一些技巧才能在表达式中操作它。这里:Print
void
int arr[] = { (Print(Param),0)... };
逗号运算符 () 用于确保 的副作用得到体现,但返回了某些内容:零 。事实上,你不能构造一个 s 的数组。,
Print
int
void
提醒一下,逗号运算符计算其左手操作数,丢弃其结果,最后返回其右手操作数。
以我的拙见,这是一个糟糕的黑客攻击。可以构建一个更清晰/明确的:
struct side_effect_t
{
side_effect_t(...) {}
};
template<typename T>
side_effect_t Print(T& arg)
{
std::cout << arg << '\n';
return {};
}
template<typename ...ParamTypes>
void Func(ParamTypes &...Param)
{
side_effect_t{ Print(Param)... };
}
评论
0赞
HolyBlackCat
9/25/2023
你的片段 ICEs GCC,呵呵。
1赞
HolyBlackCat
9/25/2023
是的,任何内部编译器错误总是一个错误。
1赞
YSC
9/25/2023
报告:gcc.gnu.org/bugzilla/show_bug.cgi?id=111592
0赞
Jarod42
9/25/2023
side_effect_t
很容易被滥用,即 ,并且不再保证订单......side_effect_t( Print(Param)... )
3赞
Quimby
9/25/2023
#2
这是 C++ 17 折叠表达式的 C++ 14 解决方法,您可以在其中编写:
template<typename ...ParamTypes>
void Func(ParamTypes &...Param)
{
(Print(Param),... );
}
Print(Param),0
调用 ,丢弃结果(如果有)并计算结果为 0。Print
int arr[] = { (Print(Param),0)... };
创建一个零数组,但对于 C++14 来说,这是为数不多的可以扩展可变参数包的地方之一。
评论
2赞
HolyBlackCat
9/25/2023
在折叠表达式中,如果您想要一些额外的健壮性,可以换行以防止用户过载。Print(Param)
void(...)
,
评论