Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error using map iterators

In my header file I have included the std::map and use the appropriate namespace.
One of my members is:

map<unsigned int, double> pT_Spam;

And in my .cpp file I attempt to do something that I have been doing frequently for some time now:

for(map<unsigned int, double>::iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) {/*code*/}

The above is even mentioned in one the examples of using std::map at cplusplus.com . Even though I have done pretty much the same in other parts of the code which cause no compile errors, on this particular line I get the following error from Cygwin:

error: conversion from `std::_Rb_tree_const_iterator<std::pair<const unsigned int, double> >' to non-scalar type `std::_Rb_tree_iterator<std::pair<const unsigned int, double> >' requested

Which seems rather strange. Any idea what might be wrong? (my header is, of course, included in my .cpp)

like image 958
jathanasiou Avatar asked Jan 06 '12 01:01

jathanasiou


3 Answers

It would seem that at the scope this loop exists, the map is const. For example, is the loop in a class method declared const, like so?

void method() const // const method
{
    // Do stuff.
}

or passed as a const argument, like this?

void function(const map<unsigned int, double>& pT_Spam)
{
    // Do stuff.
}

If it is, you must use const iterators:

for(map<unsigned int, double>::const_iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++)
{
    /*code*/
}

Or, if you're using C++11, then you should use the auto keyword:

for(auto it=pT_Spam.begin() ; it!=pT_Spam.end(); it++)
{
    /*code*/
}

Since in the case you've shown you must use const iterators, you can't use them to modify the map or the data within it. That's const correctness, and it's a good thing :).

like image 107
Liam M Avatar answered Oct 31 '22 17:10

Liam M


Well, the error says you're trying to cast a const_iterator to an iterator. You say that pT_Spam is a member. Is it a member of a const object? If it is, begin() and end() will return const_iterators.

like image 25
Peter Milley Avatar answered Oct 31 '22 17:10

Peter Milley


You need to use const_iterators for maps, so it should be:

for(map<unsigned int, double>::const_iterator it = \\and so on

Edit: As pointed out the above is right, but for completely wrong reasons (maps have non-const iterators. What was I thinking exactly? I don't know). Most likely your map is defined as const (as pointed out in another answer).

like image 2
Yuushi Avatar answered Oct 31 '22 16:10

Yuushi