populate c++ maps content in a loop scope
I try to populate the content of a c++ map within a loop scope.
#include <set>
#include <map>
map<int, set<int> > maps;
for (int i=0; i<10; i++) {
set<int> seti; // content: a set of integers
seti.insert(i);
seti.ins开发者_如何学Goert(...);
maps.insert ( pair<int,set<int> >(i,seti) );
}
The question is: does maps.insert copy the pair content? If the pair instance is invalid after each loop scope, then such code should fail.
How should I properly generate map content (with pointer and new the instance?) and how to clean up a map properly?
thanks for any suggestion for best practices.
--- UPDATE ---
map<int, set<int> >::iterator it;
int k = (*it).first;
set<int> v = (*it).second;
is now the 'v' also a copied one from the real instance stored in map?
if yes, than I have no way to 'directly' update the map content.You do not have to explicitly create the set object, as it will be created in the map when you access it with the []
operator. Hence, you can simply write
#include <set>
#include <map>
map<int, set<int> > maps;
for (int i=0; i<10; i++) {
maps[i].insert(i);
}
Yes, it copies the content. So a new copy of the set gets inserted at each iteration of the for loop. If that is what you want, you can do it more succinctly using the make_pair function:
#include <set>
#include <map>
map<int, set<int> > maps;
for (int i=0; i<10; i++) {
set<int> seti; // content
seti.insert(i);
maps.insert ( std::make_pair(i,seti) );
}
It is not clear to me why you want a set with only a single element, unless you plan to add elements to it in the future.
UPDATED: In answer to your update. As long as the value in your map is a container of a basic value type, any updates you make to it will not affect the original value you inserted into the map.
The code you have posted should work just fine. Because of regular type semantics the values will be copied where they belong. The map (and all instances of the regular types the map contains) will destruct properly when they fall out of scope.
I have to admit that the variable name maps
in the following line confused me
map<int, set<int> > maps;
It conveyed a notion that there are many maps, whereas in reality, there is only one.
Two loops are required:
- one to construct a
set
ofint
's, and - a second one to insert those
set
s into themap
.
Here is a code sample
typedef std::set< int > IntSet;
typedef std::map< int, IntSet > MapOfIntSet;
MapOfIntSet myMap; // container
for( int i = 0; i < N; ++i ) {
IntSet intSet;
for( int j = i + 1; j < N; ++j ) {
intSet.insert( j );
}
// Both the following line does the same, any one can be used
// myMap.insert( make_pair( i, intSet ) );
myMap[ i ] = intSet;
}
A complete program with output is uploaded at codepad.
Yes, the whole set is copied inside, which is a performance bottleneck. I don't like the solutions proposed because of this. And also, as you ask using pointers, you can do this one safely using boost::shared_ptr
. The code could look like this:
#include <set>
#include <map>
#include <boost/shared_ptr.hpp>
// I add typedefs for clarity
typedef boost::shared_ptr< set<int> > set_ptr;
using namespace std;
map<int, set_ptr > maps;
for (int i=0; i<10; i++) {
set_ptr seti( new set<int>()); // content
seti->insert(i);
maps.insert ( std::make_pair(i,seti) );
}
Note that now you're only copying safe pointers, that get deleted when maps
gets deleted.
精彩评论