c++ 11基于范围的for和map:可读性

C++11 range-based for and map : readability

本文关键字:for map 可读性 范围 于范围 c++      更新时间:2023-10-16

新的基于范围的for循环确实提高了可读性,并且非常易于使用。但是,请考虑以下内容:

map<Foo,Bar> FooAndAssociatedBars;
for (auto& FooAndAssociatedBar : FooAndAssociatedBars) {
    FooAndAssociatedBar.first.doSth();
    FooAndAssociatedBar.second.doSomeOtherThing();
}

这可能是一个细节,但我发现如果我可以这样做的话,它会更可读:

for ( (auto& foo, auto& bar) : FooAndAssociatedBars) {
    foo.doSth();
    bar.doSomeOtherThing();
}

你知道等效的语法吗?

编辑:

好消息:c++ 17有一个解决这个问题的提议,叫做结构化绑定(见1)。在c++ 17中,你应该能够写:

tuple<T1,T2,T3> f(/*...*/) {
    /*...*/ 
    return {a,b,c};
}
auto [x,y,z] = f(); // x has type T1, y has type T2, z has type T3

解决了这个可读性问题

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

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

不是个好主意。迟早,您会希望std::tuple具有相同的功能,并且编译器应该能够在tuple上自动使用std::get<>。在我看来,你的方法只是目前让你满意,你会发现这种方法的问题(假设它是这样实现的)。

标准委员会经过深思熟虑设计了基于范围的for循环。它比其他语言中的foreach循环要好得多,而且更短。结合auto&,你就完成了!

当然,您也可以使用lambda。

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样例实现)

自动不会工作,虽然,我还在等待多态lambdas。我的方法理论上也可以处理元组