Re: Resorting a map (copying a map to another with different Compare)
nw wrote:
Hi,
I'd like to be able to re-sort a map (a curious aspiration perhaps). I
think basically what I'd like to do is copy one map into another that
uses a different Compare function. I was wondering if there was an
easy way of doing this in general. Or what strategy I could use to do
it?
I've tried something like this:
template<class map1_type,class map2_type>
void copy_map(map1_type&m1,map2_type&m2,int depth) {
if(depth> 0) {
map1_type::const_iterator i = m1.begin();
for(;i != m1.end();++i) {
copy_map(i,m2[i->first],depth-1);
}
} else {
map1_type::const_iterator i = m1.begin();
for(;i != m1.end();++i) {
m2[i->first] = m1[i->first];
}
}
}
But this fails to even compile. Does anyone have any ideas here?
The issue is that you "depth" is not a template (compile-time) but a
function (run-time) parameter. Thus, the recursive instantiation of a
template function does not have a stop condition.. The below seems to
work (hopefully this is what you meant to do):
-----------cut here---------
#include <functional>
#include <iostream>
#include <map>
using namespace std;
template <class M1, class M2, unsigned depth>
struct MapCopier {
static M2 Copy(const M1 &src) {
M2 dst;
for (typename M1::const_iterator i1 = src.begin(); i1 != src.end();
++i1) {
typedef typename M1::mapped_type M1Next;
typedef typename M2::mapped_type M2Next;
dst[i1->first] = MapCopier<M1Next, M2Next, depth - 1>
::Copy(i1->second);
}
return dst;
}
};
template <class M1, class M2>
struct MapCopier<M1, M2, 1> {
static M2 Copy(const M1 &src) {
M2 dst(src.begin(), src.end());
return dst;
}
};
struct RevComp : public binary_function<int, int, bool>
{ bool operator()(int x, int y) const { return x > y; } };
typedef map<int, map<int, int> > IM1;
typedef map<int, map<int, int, RevComp>, RevComp> IM2;
int main() {
IM1 m1;
m1[0][0] = 7;
m1[0][1] = 8;
m1[1][0] = 9;
m1[1][1] = 10;
IM2 m2 = MapCopier<IM1, IM2, 2>::Copy(m1);
for (IM2::iterator i = m2.begin(); i != m2.end(); ++i)
for (IM2::value_type::second_type::iterator j = i->second.begin();
j != i->second.end(); ++j)
cout << "m2[" << i->first << "][" << j->first << "]=" << j->second
<< '\n';
return 0;
}
-----------cut here---------
Hope this helps,
Pavel