1
votes

I have a problem passing a map<...>::iterator object to a function as a const_iterator & on GCC:

class MyClass {


};

bool MyClass::_GetInstList(map<string,InstList>::const_iterator & it, const string & sMod)
{
    cout<<"Matched\n";
    it = tInstancesData.find(sMod);
    if( it == tInstancesData.end() ) {
        cout<<"\""<<sMod<<"\" is NOT a module\n";
        return false;
    }
    return true;
}

    bool SomeFunction()
    {

            map<string,InstList>::iterator  it;
            if( ! _GetInstList(it, SomeString) ) return false;
            it->second.Add(...);  //  Modifying element pointed by "it"

    }

My probelm is that on Visual Studio 2010 the code above works perfectly fine, but on GCC 4.1.2 I get an error saying there is no matching function to the function call, for _GetInstList(it, SomeString). The issue seems to be converting iterator to const_iterator &.

I have to take it by reference because "it" gets changed inside _GetInstList() and the caller function checks it. (The "it" pointer is changed not a pointed element).

Also, the "it" in SomeFunction() cannot be const because it changes an element.

How can I resolve this?

EDIT: For those who suggest that the problem is the conversion from iterator to const_iterator: The code compiles fine if the function prototype is changed to take const_iterator NOT as a reference, the problem is the const &.

2
Convert to const_iterator before calling? Or start with a const_iterator in the first place? Or make the code generic and accept any iterator. - R. Martinho Fernandes
Why does _GetInstList() need a const_iterator? - Adam27X
The standard says that iterator is convertible to const_iterator. It doesn't say that an iterator is a const_iterator, so the same does not apply for a reference to it. It doesn't inherit from it's const counterpart, so it is a conversion which needs a cast. - leemes
@R.MartinhoFernandes - I've done that and still got the same error. I need it as a NON-const iterator in the first place, as mentioned in the post. - StackHeapCollision
I would change your _GetInstList to accept no iterator argument and simply return a pair of a bool (true if found) and a non-const iterator (valid if found). Wouldn't that make more sense? - Andy Prowl

2 Answers

2
votes

Change your argument type to const map<string,InstList>::const_iterator& or just a map<string,InstList>::const_iterator.

Here's an example demonstrating your problem (and the solution) with simple types:

void func1(double& x){}
void func2(const double& x){}

int main()
{
    int x;
    func1(x); // error: 'func1' : cannot convert parameter 1 from 'int' to 'double &'
    func2(x); // succeeds
}
-2
votes

I think maybe this method should be redesigned anyway. Passing iterators around is messy and confusing for others to read. How hard would it be to do that?