I am trying to wrap the map iterator for keys and values. However, I seem to
run into problems with the values for const_iterator - it works for all
other combinations. Below I list my code and the compiler error. Please
help if possible. Thanks in advance.
// Compiler error
ra:/home/ssangapu/personal/C++/STL/mapIter-738>g++ main.cc
utlMapIterator. h: In method `class Object *&
ValueIterator<_ Rb_tree_iterato r<pair<const int,Object *>,const pair<const
int,Object *> &,const pair<const int,Object *> *> >::operator *()':
main.cc:84: instantiated from here
utlMapIterator. h:27: conversion from `Object *const' to `Object *&' discards
qualifiers
ra:/home/ssangapu/personal/C++/STL/mapIter-739>
//=============== ===
// utlMapIterator. h
//=============== ===
namespace utl
{
template <bool flag, typename ThenType, typename ElseType>
struct IF
{
typedef ThenType Result;
};
template <typename ThenType, typename ElseType>
struct IF<false, ThenType, ElseType>
{
typedef ElseType Result;
};
template <typename T>
class TypeTraits
{
private:
template<class U>
struct UnConst
{
typedef U Result;
enum { isConst = false };
};
template<class U>
struct UnConst<const U>
{
typedef U Result;
enum { isConst = true };
};
public:
enum { isConst = UnConst<T>::isC onst };
};
}
template <class MapIterator>
class ValueIterator : public MapIterator
{
public:
typedef utl::IF< utl::TypeTraits <typename
MapIterator::re ference>::isCon st,
const typename MapIterator::va lue_type::secon d_type&,
typename MapIterator::va lue_type::secon d_type&>::Resul t reference;
typedef utl::IF< utl::TypeTraits <typename
MapIterator::po inter>::isConst ,
typename MapIterator::va lue_type::secon d_type* const,
typename MapIterator::va lue_type::secon d_type*>::Resul t pointer;
ValueIterator(c onst MapIterator& mIter) : MapIterator(mIt er)
{ }
reference operator*() // *************** ERROR HERE *************
{
return MapIterator::op erator*().secon d;
}
pointer operator->()
{
return &**this;
}
};
template <class MapIterator>
class KeyIterator : public MapIterator
{
public:
typedef utl::IF< utl::TypeTraits <typename
MapIterator::re ference>::isCon st,
const typename MapIterator::va lue_type::first _type&,
typename MapIterator::va lue_type::first _type&>::Result reference;
typedef utl::IF< utl::TypeTraits <typename
MapIterator::po inter>::isConst ,
typename MapIterator::va lue_type::first _type* const,
typename MapIterator::va lue_type::first _type*>::Result pointer;
KeyIterator(con st MapIterator& mIter) : MapIterator(mIt er)
{ }
reference operator*() const
{
return MapIterator::op erator*().first ;
}
pointer operator->() const
{
return &**this;
}
};
template <class MapIterator>
inline
ValueIterator<M apIterator> valueIter(const MapIterator& iter)
{
return ValueIterator<M apIterator>(ite r);
}
template <class MapIterator>
inline
KeyIterator<Map Iterator> keyIter(const MapIterator& iter)
{
return KeyIterator<Map Iterator>(iter) ;
}
//=============== ===
// main.cc
//=============== ===
#include <iostream>
#include <string>
#include <map>
#include <list>
#include <functional>
#include <algorithm>
#include <iterator>
#include "utlMapIterator .h"
using namespace std;
class Object
{
public:
Object(int a) { i = a; }
int i;
};
class Print
{
public:
void operator()(Obje ct* a)
{
cout << a->i << " ";
}
};
int main()
{
map<int, Object*> m_Map;
Object o1(1*2);
m_Map.insert(ma ke_pair(1, &o1));
Object o2(2*2);
m_Map.insert(ma ke_pair(2, &o2));
Object o3(3*2);
m_Map.insert(ma ke_pair(3, &o3));
Object o4(4*2);
m_Map.insert(ma ke_pair(4, &o4));
Object o5(5*2);
m_Map.insert(ma ke_pair(5, &o5));
Object o6(6*2);
m_Map.insert(ma ke_pair(6, &o6));
cout << &o1 << " " << &o2 << " " << &o3 << " ";
cout << &o4 << " " << &o5 << " " << &o6 << endl;
cout << endl;
cout << "Keys:\n";
copy( keyIter(m_Map.b egin()), keyIter(m_Map.e nd()),
ostream_iterato r<int>(cout, " ") );
cout << endl;
cout << "Values:\n" ;
for_each( valueIter(m_Map .begin()), valueIter(m_Map .end()), Print() );
cout << endl;
cout << endl;
cout << "Keys:\n";
map<int, Object*>::const _iterator iter = m_Map.begin();
for ( iter; iter != m_Map.end(); ++iter )
{
cout << *(keyIter(iter) ) << " ";
}
cout << endl;
map<int, Object*>::itera tor iter2 = m_Map.begin();
for ( iter2; iter2 != m_Map.end(); ++iter2 )
{
cout << *(keyIter(iter2 )) << " ";
}
cout << endl;
cout << "Values:\n" ;
map<int, Object*>::const _iterator viter = m_Map.begin();
for ( viter; viter != m_Map.end(); ++viter )
{
cout << (*valueIter(vit er))->i << " "; // ************ COMPILER
ERROR ***************
}
map<int, Object*>::itera tor viter2 = m_Map.begin();
for ( viter2; viter2 != m_Map.end(); ++viter2 )
{
cout << (*valueIter(vit er2))->i << " ";
}
cout << endl;
cout << endl;
cout << endl;
cout << "Copied to a list.\nValues:\ n";
list<Object*> myList;
myList.insert( myList.end(),
valueIter(m_Map .begin()),
valueIter(m_Map .end()) );
for_each( myList.begin(), myList.end(), Print() );
cout << endl;
cout << endl;
}
run into problems with the values for const_iterator - it works for all
other combinations. Below I list my code and the compiler error. Please
help if possible. Thanks in advance.
// Compiler error
ra:/home/ssangapu/personal/C++/STL/mapIter-738>g++ main.cc
utlMapIterator. h: In method `class Object *&
ValueIterator<_ Rb_tree_iterato r<pair<const int,Object *>,const pair<const
int,Object *> &,const pair<const int,Object *> *> >::operator *()':
main.cc:84: instantiated from here
utlMapIterator. h:27: conversion from `Object *const' to `Object *&' discards
qualifiers
ra:/home/ssangapu/personal/C++/STL/mapIter-739>
//=============== ===
// utlMapIterator. h
//=============== ===
namespace utl
{
template <bool flag, typename ThenType, typename ElseType>
struct IF
{
typedef ThenType Result;
};
template <typename ThenType, typename ElseType>
struct IF<false, ThenType, ElseType>
{
typedef ElseType Result;
};
template <typename T>
class TypeTraits
{
private:
template<class U>
struct UnConst
{
typedef U Result;
enum { isConst = false };
};
template<class U>
struct UnConst<const U>
{
typedef U Result;
enum { isConst = true };
};
public:
enum { isConst = UnConst<T>::isC onst };
};
}
template <class MapIterator>
class ValueIterator : public MapIterator
{
public:
typedef utl::IF< utl::TypeTraits <typename
MapIterator::re ference>::isCon st,
const typename MapIterator::va lue_type::secon d_type&,
typename MapIterator::va lue_type::secon d_type&>::Resul t reference;
typedef utl::IF< utl::TypeTraits <typename
MapIterator::po inter>::isConst ,
typename MapIterator::va lue_type::secon d_type* const,
typename MapIterator::va lue_type::secon d_type*>::Resul t pointer;
ValueIterator(c onst MapIterator& mIter) : MapIterator(mIt er)
{ }
reference operator*() // *************** ERROR HERE *************
{
return MapIterator::op erator*().secon d;
}
pointer operator->()
{
return &**this;
}
};
template <class MapIterator>
class KeyIterator : public MapIterator
{
public:
typedef utl::IF< utl::TypeTraits <typename
MapIterator::re ference>::isCon st,
const typename MapIterator::va lue_type::first _type&,
typename MapIterator::va lue_type::first _type&>::Result reference;
typedef utl::IF< utl::TypeTraits <typename
MapIterator::po inter>::isConst ,
typename MapIterator::va lue_type::first _type* const,
typename MapIterator::va lue_type::first _type*>::Result pointer;
KeyIterator(con st MapIterator& mIter) : MapIterator(mIt er)
{ }
reference operator*() const
{
return MapIterator::op erator*().first ;
}
pointer operator->() const
{
return &**this;
}
};
template <class MapIterator>
inline
ValueIterator<M apIterator> valueIter(const MapIterator& iter)
{
return ValueIterator<M apIterator>(ite r);
}
template <class MapIterator>
inline
KeyIterator<Map Iterator> keyIter(const MapIterator& iter)
{
return KeyIterator<Map Iterator>(iter) ;
}
//=============== ===
// main.cc
//=============== ===
#include <iostream>
#include <string>
#include <map>
#include <list>
#include <functional>
#include <algorithm>
#include <iterator>
#include "utlMapIterator .h"
using namespace std;
class Object
{
public:
Object(int a) { i = a; }
int i;
};
class Print
{
public:
void operator()(Obje ct* a)
{
cout << a->i << " ";
}
};
int main()
{
map<int, Object*> m_Map;
Object o1(1*2);
m_Map.insert(ma ke_pair(1, &o1));
Object o2(2*2);
m_Map.insert(ma ke_pair(2, &o2));
Object o3(3*2);
m_Map.insert(ma ke_pair(3, &o3));
Object o4(4*2);
m_Map.insert(ma ke_pair(4, &o4));
Object o5(5*2);
m_Map.insert(ma ke_pair(5, &o5));
Object o6(6*2);
m_Map.insert(ma ke_pair(6, &o6));
cout << &o1 << " " << &o2 << " " << &o3 << " ";
cout << &o4 << " " << &o5 << " " << &o6 << endl;
cout << endl;
cout << "Keys:\n";
copy( keyIter(m_Map.b egin()), keyIter(m_Map.e nd()),
ostream_iterato r<int>(cout, " ") );
cout << endl;
cout << "Values:\n" ;
for_each( valueIter(m_Map .begin()), valueIter(m_Map .end()), Print() );
cout << endl;
cout << endl;
cout << "Keys:\n";
map<int, Object*>::const _iterator iter = m_Map.begin();
for ( iter; iter != m_Map.end(); ++iter )
{
cout << *(keyIter(iter) ) << " ";
}
cout << endl;
map<int, Object*>::itera tor iter2 = m_Map.begin();
for ( iter2; iter2 != m_Map.end(); ++iter2 )
{
cout << *(keyIter(iter2 )) << " ";
}
cout << endl;
cout << "Values:\n" ;
map<int, Object*>::const _iterator viter = m_Map.begin();
for ( viter; viter != m_Map.end(); ++viter )
{
cout << (*valueIter(vit er))->i << " "; // ************ COMPILER
ERROR ***************
}
map<int, Object*>::itera tor viter2 = m_Map.begin();
for ( viter2; viter2 != m_Map.end(); ++viter2 )
{
cout << (*valueIter(vit er2))->i << " ";
}
cout << endl;
cout << endl;
cout << endl;
cout << "Copied to a list.\nValues:\ n";
list<Object*> myList;
myList.insert( myList.end(),
valueIter(m_Map .begin()),
valueIter(m_Map .end()) );
for_each( myList.begin(), myList.end(), Print() );
cout << endl;
cout << endl;
}