我试图从矢量地图地图地图地图地图中收集所有数据,而不必在C ++中有7个循环。
以下是数据的外观:
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个循环吗?
感谢您的帮助。
答案 0 :(得分:4)
我喜欢@ 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>);
答案 1 :(得分:3)
除非更改数据类型,否则您可能会遇到循环内循环。
但是,我首先将......矢量地图的地图地图重新编写成1幅矢量地图。
我建议使用boost :: tuple或std :: tuple(C ++ 0x)创建类,但您也可以定义自己的类,并重载operator <
以便它可以用作映射键(或写比较器)
使用boost :: tuple,如果你有map<Key1, map< Key2, map<Key3, map<Key4, map<Key5, map<Key6, vector<T> > > > > > >
,你可以将其重新加工成map< boost::tuple< Key1, Key2, Key3, Key4, Key5, Key6 >, vector<T> >
。
答案 2 :(得分:2)
如果你真的必须,你可以做一些模板元编程(例如使用boost mpl)来抽象出循环。但是,正如许多人所建议的那样,原始问题的解决方案很可能比需要7个嵌套地图和矢量的解决方案更好。