[c++] C ++ 맵에서 키 반복

C ++ 맵 쌍이 아닌 키를 반복하는 방법이 있습니까?



답변

“실제”반복기가 반환하는 값을 정말로 숨겨야하는 경우 (예를 들어 표준 알고리즘과 함께 키 반복기를 사용하여 쌍 대신 키에서 작동하도록하려는 경우) Boost의 transform_iterator .

[팁 : 새 클래스에 대한 Boost 문서를 볼 때 먼저 끝에있는 “예제”를 읽으십시오. 그런 다음 나머지 부분이 무엇에 대해 이야기하고 있는지 알아낼 스포츠 기회가 있습니다. :-)]


답변

지도는 연관 컨테이너입니다. 따라서 iterator는 한 쌍의 key, val입니다. 키만 필요한 경우 쌍의 값 부분을 무시할 수 있습니다.

for(std::map<Key,Val>::iterator iter = myMap.begin(); iter != myMap.end(); ++iter)
{
Key k =  iter->first;
//ignore value
//Value v = iter->second;
}

편집 : : 외부에 키만 노출하려는 경우지도를 벡터 또는 키로 변환하고 노출 할 수 있습니다.


답변

C ++ 11에서는 반복 구문이 간단합니다. 여전히 쌍을 반복하지만 키에만 액세스하는 것은 쉽습니다.

#include <iostream>
#include <map>

int main()
{
    std::map<std::string, int> myMap;

    myMap["one"] = 1;
    myMap["two"] = 2;
    myMap["three"] = 3;

    for ( const auto &myPair : myMap ) {
        std::cout << myPair.first << "\n";
    }
}


답변

부스트없이

해당 맵에 대한 STL 반복기를 확장하면됩니다. 예를 들어 문자열을 정수로 매핑하는 경우 :

#include <map>
typedef map<string, int> ScoreMap;
typedef ScoreMap::iterator ScoreMapIterator;

class key_iterator : public ScoreMapIterator
{
  public:
    key_iterator() : ScoreMapIterator() {};
    key_iterator(ScoreMapIterator s) : ScoreMapIterator(s) {};
    string* operator->() { return (string* const)&(ScoreMapIterator::operator->()->first); }
    string operator*() { return ScoreMapIterator::operator*().first; }
};

보다 일반적인 솔루션을 위해 템플릿에서이 확장을 수행 할 수도 있습니다.

begin()end().

ScoreMap m;
m["jim"] = 1000;
m["sally"] = 2000;

for (key_iterator s = m.begin(); s != m.end(); ++s)
    printf("\n key %s", s->c_str());


답변

C ++ 17 을 사용하면 범위 기반 for 루프 내 에서 구조화 된 바인딩을 사용할 수 있습니다 ( 그에 따라 John H.의 답변을 적용 함 ).

#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> myMap;

    myMap["one"] = 1;
    myMap["two"] = 2;
    myMap["three"] = 3;

    for ( const auto &[key, value]: myMap ) {
        std::cout << key << '\n';
    }
}

불행히도 C ++ 17 표준에서는 value변수를 사용하지 않더라도 변수 를 선언해야 합니다 (용 std::ignore으로 사용할 수 없으므로이 토론을std::tie(..) 참조하십시오. ).

따라서 일부 컴파일러는 사용하지 않는 value변수 에 대해 경고 할 수 있습니다 ! 사용하지 않는 변수에 대한 컴파일 시간 경고는 내 마음에있는 어떤 프로덕션 코드에도 적용되지 않습니다. 따라서 특정 컴파일러 버전에는 적용되지 않을 수 있습니다.


답변

Ian이 언급 한보다 일반적인 템플릿 솔루션 아래에서 …

#include <map>

template<typename Key, typename Value>
using Map = std::map<Key, Value>;

template<typename Key, typename Value>
using MapIterator = typename Map<Key, Value>::iterator;

template<typename Key, typename Value>
class MapKeyIterator : public MapIterator<Key, Value> {

public:

    MapKeyIterator ( ) : MapIterator<Key, Value> ( ) { };
    MapKeyIterator ( MapIterator<Key, Value> it_ ) : MapIterator<Key, Value> ( it_ ) { };

    Key *operator -> ( ) { return ( Key * const ) &( MapIterator<Key, Value>::operator -> ( )->first ); }
    Key operator * ( ) { return MapIterator<Key, Value>::operator * ( ).first; }
};

template<typename Key, typename Value>
class MapValueIterator : public MapIterator<Key, Value> {

public:

    MapValueIterator ( ) : MapIterator<Key, Value> ( ) { };
    MapValueIterator ( MapIterator<Key, Value> it_ ) : MapIterator<Key, Value> ( it_ ) { };

    Value *operator -> ( ) { return ( Value * const ) &( MapIterator<Key, Value>::operator -> ( )->second ); }
    Value operator * ( ) { return MapIterator<Key, Value>::operator * ( ).second; }
};

모든 크레딧은 Ian에게 … 고마워 Ian.


답변

당신은 map_keys를 찾고 있습니다.

BOOST_FOREACH(const key_t key, the_map | boost::adaptors::map_keys)
{
  // do something with key
}