11

新的基于范围的 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

解决了这个可读性问题

4

3 回答 3

10

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

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

    // ...
}
于 2013-03-20T14:25:02.063 回答
1

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

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

于 2013-03-20T15:33:02.017 回答
0

当然,您始终可以使用 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 示例实现

不过,自动不起作用,我仍在等待多态 lambda。我的方法理论上也能够处理元组。

于 2013-03-20T15:33:01.377 回答