does map find guarantee to not copy mapped value?

P

PeteUK

Hello,

I find myself writing a lot of code like the one below where I find
something out of a map and then use a reference to second to
interrogate the mapped object:

#include <iostream>
#include <map>

class Expensive { /* lots of stuff here... */ };

int main()
{
std::map<int,Expensive> m;
m.insert(std::make_pair(1,Expensive(3)));

// and then later
std::map<int,Expensive>::const_iterator it = m.find(1);
const Expensive& expensive = (*it).second;
// use expensive here - is this safe?
}

Is this practice safe? I've just determined on VC9 compiler that the
find doesn't do any copies, but wondered if the standard mandates
this?

Thanks,

Pete
 
K

Kai-Uwe Bux

PeteUK said:
Hello,

I find myself writing a lot of code like the one below where I find
something out of a map and then use a reference to second to
interrogate the mapped object:

#include <iostream>
#include <map>

class Expensive { /* lots of stuff here... */ };

int main()
{
std::map<int,Expensive> m;
m.insert(std::make_pair(1,Expensive(3)));

// and then later
std::map<int,Expensive>::const_iterator it = m.find(1);
const Expensive& expensive = (*it).second;
// use expensive here - is this safe?
}

Is this practice safe?

Operations on map don't invalidate references unless they erase the element
referred to. The same guarantee applies to iterators and pointers into the
map.
I've just determined on VC9 compiler that the
find doesn't do any copies, but wondered if the standard mandates
this?

Yes: [23.1/11] and [23.1.2/8] and the absence of invalidate-clauses in the
section about std::map.


Best

Kai-Uwe Bux
 
P

PeteUK

PeteUK said:
I find myself writing a lot of code like the one below where I find
something out of a map and then use a reference to second to
interrogate the mapped object:
#include <iostream>
#include <map>
class Expensive { /* lots of stuff here... */ };
int main()
{
std::map<int,Expensive> m;
m.insert(std::make_pair(1,Expensive(3)));
        // and then later
std::map<int,Expensive>::const_iterator it = m.find(1);
const Expensive& expensive = (*it).second;
// use expensive here - is this safe?
}
Is this practice safe?

Operations on map don't invalidate references unless they erase the element
referred to. The same guarantee applies to iterators and pointers into the
map.
I've just determined on VC9 compiler that the
find doesn't do any copies, but wondered if the standard mandates
this?

Yes: [23.1/11] and [23.1.2/8] and the absence of invalidate-clauses in the
section about std::map.

Best

Kai-Uwe Bux

Kai-Uwe Bux,

I appreciate your clarification of this.

Pete
 
M

Marc

        std::map<int,Expensive> m;
        m.insert(std::make_pair(1,Expensive(3)));

As a side note, you may want to avoid this syntax, as it may cause
more copies than needed. Replacing std::make_pair with
std::map<...>::value_type saves one copy in libstdc++ (or 2 in C++0x
mode, because make_pair becomes horrible). std::make_pair(1,3) works
too.

(Yes, I know that most of those copies are actually moves in C++0x)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top