2013-03-20 266 views
11

新的基於範圍的for循環確實提高了可讀性,並且非常易於使用。然而,考慮以下因素:C++ 11基於範圍的for和map:可讀性

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 

解決了這個問題,可讀性

+0

編譯器會如何猜測'Foo'和'Bar'是指什麼? – 2013-03-20 14:50:20

+0

@PeteBecker嗯,foo只是一個方便的方式來說「名字foo std :: pair的左邊部分」。絕對而言,可以在編譯時做到這一點:這只是一個符號方便。我想知道是否有可能通過重載或類似的方式獲得這樣的效果 – 2013-03-20 15:05:24

+0

是的,當然可以要求編譯器知道'std :: pair'或查找任何具有名爲'first'和'秒';這很專業,可能不適合標準化。下一個請求將是'元組'的所有元素... – 2013-03-20 15:15:45

回答

10

有沒有這樣的事情,只要你想。最接近的是申報循環內的變量:

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

    // ... 
} 
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); 

Hackish sample implementation at LWS

汽車將無法工作,雖然,我仍然在等待多態lambda表達式。我的方法在理論上也能夠處理元組。

1

不是一個好主意。遲早,你會想要std::tuple相同,編譯器應該能夠自動使用tuple上的std::get<>。在我看來,你的方法現在只讓你滿意,而且你會發現這種方法存在問題(假設它是以這種方式實現的)。

標準委員會已經深入考慮設計了基於範圍的循環。它比其他語言的foreach循環更好,並且它更短。將它與auto&結合起來,就完成了!

+1

「不是一個好主意,遲早你會想要一個std :: tuple,並且編譯器應該能夠自動地在元組上使用std :: get <>。那問題是? – Cubic 2013-03-20 17:12:54

+0

編譯器的更多需求。 – Ajay 2013-03-20 17:36:01

+0

如何?我發現任何這樣的語言特性將被定義爲調用'std :: get'(很可能不合格的'get'),因此支持'std :: pair'和'std :: tuple'以及任何用戶定義的'元組「像容器自動。 – Grizzly 2013-03-23 20:40:20