一个基于范围的for循环遍历几个元组的简洁符号表示是什么?

3

有没有更简单(更短)的方法将此代码片段写成循环形式:

for (auto [a, b]: {pair<int, int>{1, 2}, pair<int, int>{3, 4}})
  foo(a, b);

最好让初始化列表尽可能接近这个格式,虽然这个格式无法编译通过:
for (auto [a, b]: {{1, 2}, {3, 4}})
  foo(a, b);

coughcough o... - YSC
4
做这样的事情:{ foo(1, 2); foo(3, 4); },即使条件为假;-) - Jarod42
@Jarod42 你在法律上是正确的!;-) - Paul Jurczak
4个回答

5
作为一种强类型语言,C++编译器推断类型的模糊度是有限的。例如,两个未指定花括号的级别就是这种情况之一。
您可以使用简单的typedef来缩短代码:
using pair_list = std::initializer_list<std::pair<int, int>>;

for (auto [a, b]: pair_list{{1, 2}, {3, 4}})
  foo(a, b);
这里有实时演示。您可以根据需要优化/选择临时类型。

2
哦。我正在处理类和推导指南。 - Quentin

4
由于类型推导指南(deduction guide),您可以在C++17中执行以下操作:
for (auto [a, b]: {std::pair{1, 2}, std::pair{3, 4}})
    foo(a, b);

甚至更多
for (auto [a, b]: {std::pair{1, 2}, {3, 4}})
    foo(a, b);

太棒了!由于我通常不使用 std::,你的解决方案是最简洁和灵活的。 - Paul Jurczak
沿着这条线:for (auto [i, j, k]: {tuple{.1, .5, 5}, tuple{.4, .5, 6}}) - Paul Jurczak
2
@PaulJurczak - 你可以再更短一点。只有第一个条目必须明确为一对。第二个将基于第一个进行推断。 - StoryTeller - Unslander Monica
@scales terribly是什么意思?编译时间惩罚吗? - Paul Jurczak
@Paul 列表中的每个元素都需要添加一个类型名称前缀。但我还没看到 StoryTeller 的评论,他否定了我的观察结果。没关系 :)。 - rubenvb

2
有一个更简单的方法,它涉及构建一个临时的std::map。你可以像这样做:
for (auto [a, b]: map<int, int>{{1, 2}, {3, 4}})
        foo(a, b);

这个编译通过了,可以在这里查看。

或者像@Jarod42建议的那样,你也可以使用std::initializer_list<std::pair<int, int>>

for (auto [a, b]: std::initializer_list<std::pair<int, int>>{{1, 2}, {3, 4}})

你需要输入更多的内容。:)

std::initializer_list<std::pair<int, int>> 也可以完成这个任务。 - Jarod42
@Jarod42:谢谢。已更新。 - P.W
map<int, int> 看起来不错,但在内部循环中可能会降低性能。 - Paul Jurczak
@PaulJurczak:是的,我在追求最短的代码。 :) - P.W

1

这个模板或许能帮上忙:

template <class T>
constexpr auto asPairs(std::initializer_list<std::pair<T, T>> args)
{
   return args;
}

它可以被实例化并像下面这样使用。
for (auto [a, b] : asPairs<int>({{1, 2}, {3, 4}}))
    foo(a, b);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接