2011-08-19 2 views
0

벡터의지도의지도의지도의지도의지도의지도의지도로부터 모든 데이터를 모으려고 노력하고 있습니다 7 C++의 루프. 여기벡터지도의지도지도의지도의지도의지도를 반복하는 방법

데이터가 모습입니다 :

Map 1=>Map 1.1=>Map 1.1.1=>Map 1.1.2=>Map 1.1.3=>Map 1.1.4=>Vector 1.1.5=>Elem 1 
                     =>Elem 2 
     Map 1.2=>Map 1.2.1=>Map 1.2.2=>Map 1.2.3=>Map 1.2.4=>Vector 1.2.5=> Elem 1 
                     =>Elem 2 
Map 2 =>Map 1.1=>Map 1.1.1=>Map 1.1.2=>Map 1.1.3=>Map 1.1.4=>Vector 1.1.5=>Elem 1 
                     =>Elem 2 
     Map 1.2=>Map 1.2.1=>Map 1.2.2=>Map 1.2.3=>Map 1.2.4=>Vector 1.2.5=>Elem 1 
                     =>Elem 2 

그래서 내가지도에 모든 맵에서 모든 Elem 모델 1, Elem 모델 2를 수집하기 위해 노력하고 있습니다.

누가 각지도를 통해 명백한 루프 대신 C++에서 7 개의 루프를 만들 수 있습니까?

도움 주셔서 감사합니다.

+30

하지 ......... –

+7

이유는 중첩 맵과 벡터를해야합니까? map-of-a-vector를 반복하는 대신 코드를 구조화하여 불필요하게 만들 수있는 더 좋은 방법이 있습니다. – Alex

+6

당신은 7 개의 중첩 된 for 루프를 작성하는 것을 꺼려하기 때문에 이것이 약간 멀리 간다는 것을 분명히 느낄 수 있습니다. 그러나 7 개의 중첩 된 맵을 가지고 있다면 무엇을 할 수 있습니까? 이것은 조금 우습다, 대안이 있어야합니다. 당신이 달성하고자하는 것을 설명한다면, 누군가는 더 좋은 방법을 제안 할 것입니다. – john

답변

3

저는 inflagranti의 아이디어를 좋아합니다. 따라서 유틸리티에 대한 소유권을 주장하지 않고 모든 것을 반복하는 for-each 템플릿이 있습니다. 여기서는 pretty printeris_container 특성을 사용합니다. 여기서는 복제하지 않았습니다.

업데이트 : 이제 벌거 벗은 값 유형과 쌍 값 유형 모두를 처리하기 위해 완전히 연습했습니다.

업데이트 2 : @Luc Danton 덕분에 구현 클래스가 단순화되었습니다.

#include <algorithm> 

#include "prettyprint.hpp"  
using namespace pretty_print; // for "is_container" trait 

template <typename T> struct is_pair : public std::false_type { }; 
template <typename S, typename T> struct is_pair<std::pair<S,T>> : public std::true_type { }; 

template <typename T> struct final_value { typedef T type; }; 
template <typename S, typename T> struct final_value<std::pair<S,T>> { typedef T type; }; 

template <typename Iter, typename F> void for_each_recursive(Iter begin, Iter end, F f); 

template <typename F, bool Recurse> struct for_each_rec_impl; 

template <typename F> 
struct for_each_rec_impl<F, false> 
{ 
    template <typename Iter> 
    static typename std::enable_if<is_pair<typename std::iterator_traits<Iter>::value_type>::value, void>::type 
    go(Iter begin, Iter end, F f) 
    { 
    for (Iter it = begin; it != end; ++it) f(it->second); 
    } 

    template <typename Iter> 
    static typename std::enable_if<!is_pair<typename std::iterator_traits<Iter>::value_type>::value, void>::type 
    go(Iter begin, Iter end, F f) 
    { 
    for (Iter it = begin; it != end; ++it) f(*it); 
    } 
}; 

template <typename F> 
struct for_each_rec_impl<F, true> 
{ 
    template <typename Iter> 
    static typename std::enable_if<is_pair<typename std::iterator_traits<Iter>::value_type>::value, void>::type 
    go(Iter begin, Iter end, F f) 
    { 
    for (Iter it = begin; it != end; ++it) 
     { 
     for_each_recursive(it->second.begin(), it->second.end(), f); 
     } 
    } 

    template <typename Iter> 
    static typename std::enable_if<!is_pair<typename std::iterator_traits<Iter>::value_type>::value, void>::type 
    go(Iter begin, Iter end, F f) 
    { 
    for (Iter it = begin; it != end; ++it) 
     { 
     for_each_recursive(it->begin(), it->end(), f); 
     } 
    } 
}; 

template <typename Iter, typename F> 
void for_each_recursive(Iter begin, Iter end, F f) 
{ 
    typedef typename std::iterator_traits<Iter>::value_type value_type; 
    typedef typename final_value<value_type>::type type; 

    for_each_rec_impl<F, is_container<type>::value>::go(begin, end, f); 
} 

사용법 : for_each_recursive(v.begin(), v.end(), my_predicate<final_value_type>);

2

정말로 필요한 경우, 루프를 추상화하기 위해 일부 템플릿 메타 프로그래밍 (예 : 부스트 mpl 사용)을 수행 할 수 있습니다. 그러나 많은 사람들이 제안했듯이 7 개의 중첩 된 맵과 벡터가 필요한 것보다 원래의 문제에 대한 더 나은 해결책이 될 수 있습니다.

3

데이터 유형을 변경하지 않으면 루프 내에서 루프가 발생합니다.

그러나지도의지도지도를 .... 벡터지도 1 개에 다시 작성하는 것으로 시작합니다. 클래스를 만들려면 boost :: tuple 또는 std :: tuple (C++ 0x) 중 하나를 사용하는 것이 좋지만 직접 정의 할 수도 있고 operator <을 오버로드하여지도 키로 사용할 수도 있습니다. 비교기)

map<Key1, map< Key2, map<Key3, map<Key4, map<Key5, map<Key6, vector<T> > > > > > >이있는 경우 boost :: tuple을 사용하면 map< boost::tuple< Key1, Key2, Key3, Key4, Key5, Key6 >, vector<T> >으로 다시 처리 할 수 ​​있습니다.

+0

C++ 0x는 이제 C++ 11 – Xirdus

+0

@Xirdus : 아마도 표준이 게시되면 될 것입니다. 나는 아직도 숨을 멈추지 않고있다. –