问题 C ++ 11基于范围的和map:可读性[重复]


这个问题在这里已有答案:


7329
2018-03-20 14:21


起源

编译器如何猜测是什么 Foo 和 Bar 本来是指? - Pete Becker
@Pete:OP的请求似乎并不那么不合理(好吧,除了类型推断可能):它与使用它没有那么不同 std::tie 打开一对/元组。语法可能意味着“定义变量 foo 和 bar 在循环之前(在本例中作为引用包装器),并在每次迭代时执行 tie(foo, bar) = *it“。它也可以在其他地方使用,例如解包函数的结果,在函数中返回多个值: (bool inserted, set<int>::iterator it) = mySet.insert(42);。 [...] - Luc Touraille
@LucTouraille - std::tie 在库中,而不是编译器。因此,这种方法也需要编译器了解有关标准库的更多详细信息。 - Pete Becker
好吧,我用过 std::tie 仅作为可能实现的示例(甚至不起作用),但编译器可以自由地生成任何代码来提供此行为。 begin 和 end 也在库中,但它们用于提供基于范围的for循环语法。 - Luc Touraille
可以使语法适用于任何支持的类型 std::get (对,元组,数组,......)。 OP的代码可以转换成 for (auto & tmp : FooAndAssociatedBars) { auto & foo = std::get<0>(tmp); auto & bar = std::get<1>(tmp); ... };我给出的示例代码可以进行类似的转换: auto & tmp = mySet.insert(42); bool inserted = std::get<0>(tmp); set<int>::iterator it = std::get<1>(tmp);。这甚至可以允许类型推断。 - Luc Touraille


答案:


没有你想要的东西。最接近的是在循环内声明变量:

for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
    auto& foo = FooAndAssociatedBar.first;
    auto& bar = FooAndAssociatedBar.second;

    // ...
}

10
2018-03-20 14:25





不是个好主意。迟早,你会想要一个相同的 std::tuple,编译器应该可以使用 std::get<> 在...上 tuple 自动。在我看来,你的方法目前只取悦你,你会发现这种方法存在问题(假设它是以这种方式实现的)。

标准委员会已经设计了基于范围的循环,并深入考虑。它比。更好 foreach 用其他语言循环,它更短。结合它 auto& 你完成了!


1
2018-03-20 15:33



“不是一个好主意。迟早,对于std :: tuple你会想要相同的,编译器应该能够自动在元组上使用std :: get <>。”问题是什么? - Cubic
编译器提出了更多要求。 - Ajay
怎么会这样?我看到任何这样的语言特征的方式将被定义为调用 std::get (完全不合格 get 更可能)因此支持 std::pair 和 std::tuple 和任何用户定义 tuple 像容器一样自动。 - Grizzly
确切地说,这是我的观点。你对编译器的要求太高了。它增加了复杂性,模糊性,更复杂的错误消息,不同编译器供应商之间的斗争。 - Ajay


当然,你总是有可能使用lambdas。

std::map<int, const char*> m { { 4, "hello" }, { 11, "c++" } };
convenient_for_each(m, [](int a, const char* b) {
    std::cout << b << a << std::endl;
  });
convenient_for_each(m, [](std::pair<int, const char> p) {
    std::cout << p.first << p.second << std::endl;
  });

或者包裹为宏(不推荐)

FOREACH((int a, const char* b), m, std::cout << a << b << std::endl);
FOREACH((std::pair<int, const char*> p), m, std::cout << p.first << p.second << std::endl);

在LWS上实施Hackish示例

虽然Auto不会工作,但我还在等待多态lambda。我的方法在理论上也能够处理元组。


0
2018-03-20 15:33