[c++] std :: map과 함께 범위 기반 for () 루프를 사용하는 방법은 무엇입니까?

C ++ 11 범위 기반 for () 루프의 일반적인 예는 항상 다음과 같이 간단합니다.

std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
     std::cout << xyz << std::endl;
}

어떤 경우에는 xyz입니다 int. 그러나지도와 같은 것이 있으면 어떻게됩니까? 이 예제에서 변수의 유형은 무엇입니까?

std::map< foo, bar > testing = { /*...blah...*/ };
for ( auto abc : testing )
{
    std::cout << abc << std::endl;         // ? should this give a foo? a bar?
    std::cout << abc->first << std::endl;  // ? or is abc an iterator?
}

통과하는 컨테이너가 간단한 경우 범위 기반 for () 루프가 반복자가 아닌 각 항목을 제공하는 것처럼 보입니다. 좋은 점입니다 … 반복자라면, 우리가 항상해야 할 일은 어쨌든 그것을 역 참조하는 것입니다.

그러나 나는지도와 멀티 맵과 같은 것들에 관해서는 무엇을 기대 해야하는지 혼란 스럽습니다.

(나는 여전히 g ++ 4.4를 사용하고 있지만 범위 기반 루프는 g ++ 4.6 이상이므로 아직 시도 할 기회가 없었습니다.)



답변

컨테이너의 각 요소 map<K, V>::value_typetypedeffor std::pair<const K, V>입니다. 결과적으로 C ++ 17 이상에서는 다음과 같이 작성할 수 있습니다.

for (auto& [key, value]: myMap) {
    std::cout << key << " has value " << value << std::endl;
}

또는

for (const auto& [key, value]: myMap) {
    std::cout << key << " has value " << value << std::endl;
}

값을 수정하지 않으려는 경우

C ++ 11 및 C ++ 14에서는 향상된 for루프를 사용하여 각 쌍을 자체적으로 추출한 다음 키와 값을 수동으로 추출 할 수 있습니다.

for (const auto& kv : myMap) {
    std::cout << kv.first << " has value " << kv.second << std::endl;
}

값의 읽기 전용보기를 원하는 경우 kv변수 표시를 고려할 수도 있습니다 const.


답변

C ++ 17에서는이를 구조적 바인딩 이라고 하며 다음을 허용합니다.

std::map< foo, bar > testing = { /*...blah...*/ };
for ( const auto& [ k, v ] : testing )
{
  std::cout << k << "=" << v << "\n";
}


답변

이 백서에서 : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2049.pdf

for( type-specifier-seq simple-declarator : expression ) statement

문법적으로

{
    typedef decltype(expression) C;
    auto&& rng(expression);
    for (auto begin(std::For<C>::begin(rng)), end(std::For<C>::end(rng)); begin != end; ++ begin) {
        type-specier-seq simple-declarator(*begin);
        statement
    }
}

따라서 abc귀하의 경우에 무엇이 있을지 분명히 알 수 있습니다 std::pair<key_type, value_type >. 인쇄를 위해 다음 abc.first과 같이 하여 각 요소에 액세스 할 수 있습니다.abc.second


답변

맵에서 키 / 값만보고 부스트를 사용하려는 경우 범위 기반 루프와 함께 부스트 어댑터를 사용할 수 있습니다.

for (const auto& value : myMap | boost::adaptors::map_values)
{
    std::cout << value << std::endl;
}

동등한 boost :: adaptors :: key_values가 있습니다

http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/adaptors/reference/map_values.html


답변

foo 및 bar의 복사 할당 연산자가 저렴하면 (예 : int, char, 포인터 등) 다음을 수행 할 수 있습니다.

foo f; bar b;
BOOST_FOREACH(boost::tie(f,b),testing)
{
  cout << "Foo is " << f << " Bar is " << b;
}


답변