简体   繁体   中英

Can't dereference the mapped_type of a map const iterator

Given the code in Visual Studio 2010:

void Foo::Bar() const
{
    map_t::const_iterator iter(my_map_.find(key));

    if(my_map_.end() != iter)
        DoStuff(iter->second);
}

Do stuff will take the mapped_type by value. The mapped type is a copyable, movable, assignable type.

I get error messages that the key/value pair can't be copied when trying to access second. Even if I write on their own lines:

iter->second;
(*iter).second;

to ensure it's nothing to do with DoStuff...

I presume the iterator is making a copy of the key/value pair before returning operator-> or operator*.

How do I get a copy of the mapped type?

EDIT:

The map itself is of unsigned shorts to boost variants, roughly as such:

typedef struct{} empty_t;
typedef boost::variant<empty_t, double, long, some POD types> variant_t;
typedef std::map<unsigned short, variant_t> map_t;

And then as a private member of the class:

map_t my_map_;

And to be clear, the problem is not in passing to DoStuff. I can remove that line, and simply dereference the iterator and access second, and that will cause the compiler error.

if(my_map_.end() != iter)
        iter->second; //Doesn't do anything, but illustrates the error.

EDIT Answer invalid given question update as a result of boost::variant (will update with final answer once the rest of the problem information is available).

If DoStuff takes it's variable by reference or by value and you're passing the variable directly from a const_iterator then DoStuff must have a const reference or const value overloaded function call (unless the object type has a default const to non-const conversion available). Otherwise the compiler complains because your treating a const element as a non-const.

Another option is to assign iter->second to another variable (via constructor or assignment depending on the element type) and pass that into DoStuff -- but it's better to define a const overload version of the function.

I figured it out.

WAYYYYY away from this code, and a couple abstractions deep, the iterators to the map were being passed to std::partition! You can't partition a map, it seems.

I copied the contents of the map into a local vector and continued processing from there, and it cleared up all the error messages.

I have no idea why the compiler was getting so throughly confused. The problem code was somewhere completely unrelated. But it doesn't matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM