Compile error using map iterators

10,048

Solution 1

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 :).

Solution 2

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.

Solution 3

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).

Solution 4

for(map::iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++)

chage it to

for(map::const_iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++)

As it is pointing to constant value, so the iterator must be also of const type.

Share:
10,048
jathanasiou
Author by

jathanasiou

Computer developer and overall nerd. Big fan of videogames, tech, tabletop RPGs and other geeky fields.

Updated on June 25, 2022

Comments

  • jathanasiou
    jathanasiou almost 2 years

    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)

  • jathanasiou
    jathanasiou over 12 years
    Won't that cause issues when altering their value(it++)? Also, I have been using regular iterators for similar loops so far and never had problems.
  • Peter Milley
    Peter Milley over 12 years
    Um, what? map has non-const iterators.
  • Kerrek SB
    Kerrek SB over 12 years
    @JohnAthanasiou: A mutable const-iterator is not the same as a const non-const iterator! Think T const * vs T * const.
  • Peter Milley
    Peter Milley over 12 years
    John: const_iterators aren't themselves const, they just refer to a const object.
  • jathanasiou
    jathanasiou over 12 years
    Not sure to be honest, it's a declared private member of my 'nbclassifier' class, while the method that performs the loop is a member of that class as well.
  • Aaron McDaid
    Aaron McDaid over 12 years
    An alternative is to mark the member as mutable. But don't tell anyone I told you that :-)
  • Captain Obvlious
    Captain Obvlious over 12 years
    -.25 for using auto in a way that kills kittens. ;)
  • Aaron McDaid
    Aaron McDaid over 12 years
    An alternative is to mark the member as mutable. But don't tell anyone I told you that :-)
  • jathanasiou
    jathanasiou over 12 years
    The method running the loop is indeed const, and that makes me understand why the map is const in it's scope as well. Considering I don't need to edit it in this method, const iterators seem to the answer.
  • Peter Milley
    Peter Milley over 12 years
    Const is coming in somewhere. If the member variable isn't declared const, and if the method isn't declared const, then maybe the method is being called on a const object (which would make the member variable implicitly const). Does the compiler error come with a call stack? EDIT: wait, it would have to be a const method if it's being called on a const object.
  • Liam M
    Liam M over 12 years
    @Chet Simpson Herb Sutter says my kittens are safe :).
  • Erik Aronesty
    Erik Aronesty over 8 years
    Where in the error does it say that? it says : conversion from GARBAGE to non-scalar type LINE_NOISE requested.
  • vappolinario
    vappolinario over 8 years
    What would be the problem with the auto in this case?