저는 inflagranti의 아이디어를 좋아합니다. 따라서 유틸리티에 대한 소유권을 주장하지 않고 모든 것을 반복하는 for-each 템플릿이 있습니다. 여기서는 pretty printer의 is_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>);
하지 ......... –
이유는 중첩 맵과 벡터를해야합니까? map-of-a-vector를 반복하는 대신 코드를 구조화하여 불필요하게 만들 수있는 더 좋은 방법이 있습니다. – Alex
당신은 7 개의 중첩 된 for 루프를 작성하는 것을 꺼려하기 때문에 이것이 약간 멀리 간다는 것을 분명히 느낄 수 있습니다. 그러나 7 개의 중첩 된 맵을 가지고 있다면 무엇을 할 수 있습니까? 이것은 조금 우습다, 대안이 있어야합니다. 당신이 달성하고자하는 것을 설명한다면, 누군가는 더 좋은 방법을 제안 할 것입니다. – john