By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,711 Members | 2,144 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,711 IT Pros & Developers. It's quick & easy.

Map Iterator is wrapped for keys and values - compiler error

P: n/a
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_iterator<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>::isConst };
};
}

template <class MapIterator>
class ValueIterator : public MapIterator
{
public:

typedef utl::IF< utl::TypeTraits<typename
MapIterator::reference>::isConst,
const typename MapIterator::value_type::second_type&,
typename MapIterator::value_type::second_type&>::Result reference;

typedef utl::IF< utl::TypeTraits<typename
MapIterator::pointer>::isConst,
typename MapIterator::value_type::second_type* const,
typename MapIterator::value_type::second_type*>::Result pointer;

ValueIterator(const MapIterator& mIter) : MapIterator(mIter)
{ }

reference operator*() // *************** ERROR HERE *************
{
return MapIterator::operator*().second;
}

pointer operator->()
{
return &**this;
}
};

template <class MapIterator>
class KeyIterator : public MapIterator
{
public:

typedef utl::IF< utl::TypeTraits<typename
MapIterator::reference>::isConst,
const typename MapIterator::value_type::first_type&,
typename MapIterator::value_type::first_type&>::Result reference;

typedef utl::IF< utl::TypeTraits<typename
MapIterator::pointer>::isConst,
typename MapIterator::value_type::first_type* const,
typename MapIterator::value_type::first_type*>::Result pointer;

KeyIterator(const MapIterator& mIter) : MapIterator(mIter)
{ }

reference operator*() const
{
return MapIterator::operator*().first;
}

pointer operator->() const
{
return &**this;
}
};

template <class MapIterator>
inline
ValueIterator<MapIterator> valueIter(const MapIterator& iter)
{
return ValueIterator<MapIterator>(iter);
}

template <class MapIterator>
inline
KeyIterator<MapIterator> keyIter(const MapIterator& iter)
{
return KeyIterator<MapIterator>(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()(Object* a)
{
cout << a->i << " ";
}
};

int main()
{
map<int, Object*> m_Map;
Object o1(1*2);
m_Map.insert(make_pair(1, &o1));

Object o2(2*2);
m_Map.insert(make_pair(2, &o2));

Object o3(3*2);
m_Map.insert(make_pair(3, &o3));

Object o4(4*2);
m_Map.insert(make_pair(4, &o4));

Object o5(5*2);
m_Map.insert(make_pair(5, &o5));

Object o6(6*2);
m_Map.insert(make_pair(6, &o6));

cout << &o1 << " " << &o2 << " " << &o3 << " ";
cout << &o4 << " " << &o5 << " " << &o6 << endl;

cout << endl;
cout << "Keys:\n";
copy( keyIter(m_Map.begin()), keyIter(m_Map.end()),
ostream_iterator<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*>::iterator 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(viter))->i << " "; // ************ COMPILER
ERROR ***************
}
map<int, Object*>::iterator viter2 = m_Map.begin();
for ( viter2; viter2 != m_Map.end(); ++viter2 )
{
cout << (*valueIter(viter2))->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;
}
Jul 19 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.