Initializing a vector in a map

E

eriwik

I use the following structure to store filenames for one or more "sets"
grouped together by a number:

map<int, map<string> > fileSets;

As arguments to the constructor I send a vector<vector<string> > where
each vector<string> contains the filenames of one set. The function
getNumber() calculates a number from the filename. The constructor then
looks like this:

Files::Files(vector<vector<string> > files&)
{
// Add files to the sets
// Loop throught all sets
for (size_t i = 0; i < files.size(); ++i)
{
vector<string>::iterator iter = files.begin();
vector<string>::iterator end = files.end();
// Add a file to fileSets[number][set]
for(; iter != end; ++iter)
{
fileSets[getNumber(*iter)] = *iter;
}
}
}

The reason that I need the first (outer) map is that the number
returned from getNumber() is very large but I don't have that many
files and there can be gaps in the numbers and so on. However I really
don't need the second (inner) map, a vector would work just as well
since I know the number of sets when the constructor is called
(files.size()).

So my question is: Is it possible to somehow "initialize" the vector in
the map to have a certain number of elements? That is if I do
fileSets[######] and that element does not already exist then a new
vector<string> will be created with a specified number of elements
allocated, so that I can then index into the vector and assigns to the
specified element?

Something like this:

Files::Files(vector<vector<string> > files&) :
fileSets(map<vector<string>(files.size()) >)

or something like that?
 
V

Victor Bazarov

I use the following structure to store filenames for one or more
"sets" grouped together by a number:

map<int, map<string> > fileSets;

Can't do that. 'map' requires two arguments. So you need to do

map<int, map<string, ???> > fileSets;

or

map<int, map<???, string> > fileSets;

Or, did you mean

map<int, vector<string> > fileSets;

???
As arguments to the constructor I send a vector<vector<string> > where
each vector<string> contains the filenames of one set. The function
getNumber() calculates a number from the filename. The constructor
then looks like this:

Files::Files(vector<vector<string> > files&)
{
// Add files to the sets
// Loop throught all sets
for (size_t i = 0; i < files.size(); ++i)
{
vector<string>::iterator iter = files.begin();
vector<string>::iterator end = files.end();
// Add a file to fileSets[number][set]
for(; iter != end; ++iter)
{
fileSets[getNumber(*iter)] = *iter;
}
}
}

The reason that I need the first (outer) map is that the number
returned from getNumber() is very large but I don't have that many
files and there can be gaps in the numbers and so on. However I really
don't need the second (inner) map, a vector would work just as well
since I know the number of sets when the constructor is called
(files.size()).

So my question is: Is it possible to somehow "initialize" the vector
in the map to have a certain number of elements?


Yes. RTFM about what constructors are available for 'std::vector'.
That is if I do
fileSets[######] and that element does not already exist then a new
vector<string> will be created with a specified number of elements
allocated, so that I can then index into the vector and assigns to the
specified element?

Something like this:

Files::Files(vector<vector<string> > files&) :
fileSets(map<vector<string>(files.size()) >)

or something like that?

Well, not exactly like that. 'map' cannot be initialised. You can,
of course, assign a vector of a particular size to the element of the
map. Use 'insert' instead of indexing to do that.

fileSets.insert(std::make_pair(getNumber(*iter),files));

V
 
E

eriwik

Victor said:
Can't do that. 'map' requires two arguments. So you need to do

Sorry about that, it should be

map said:
As arguments to the constructor I send a vector<vector<string> > where
each vector<string> contains the filenames of one set. The function
getNumber() calculates a number from the filename. The constructor
then looks like this:

Files::Files(vector<vector<string> > files&)
{
// Add files to the sets
// Loop throught all sets
for (size_t i = 0; i < files.size(); ++i)
{
vector<string>::iterator iter = files.begin();
vector<string>::iterator end = files.end();
// Add a file to fileSets[number][set]
for(; iter != end; ++iter)
{
fileSets[getNumber(*iter)] = *iter;
}
}
}

The reason that I need the first (outer) map is that the number
returned from getNumber() is very large but I don't have that many
files and there can be gaps in the numbers and so on. However I really
don't need the second (inner) map, a vector would work just as well
since I know the number of sets when the constructor is called
(files.size()).

So my question is: Is it possible to somehow "initialize" the vector
in the map to have a certain number of elements?


Yes. RTFM about what constructors are available for 'std::vector'.
That is if I do
fileSets[######] and that element does not already exist then a new
vector<string> will be created with a specified number of elements
allocated, so that I can then index into the vector and assigns to the
specified element?

Something like this:

Files::Files(vector<vector<string> > files&) :
fileSets(map<vector<string>(files.size()) >)

or something like that?

Well, not exactly like that. 'map' cannot be initialised. You can,
of course, assign a vector of a particular size to the element of the
map. Use 'insert' instead of indexing to do that.

fileSets.insert(std::make_pair(getNumber(*iter),files));


This would insert the wrong pair<int, vector<string> > into fileSets,
what I would like to do is insert one file from each set (inner vector)
at each element in the outer map.

What I wanted was this: When the []-operator is used with a key that
does not exist in the map a new element is created using the default
constructor (and a reference to this element returned is then
returned). I was hoping for a way to use another constructor instead of
the default one (in this case vector<string>(files.size()) ). However
after some more research I see that this is not possible.
 
V

Victor Bazarov

Victor said:
[..some assumptions, apparently wrong..]

This would insert the wrong pair<int, vector<string> > into fileSets,
what I would like to do is insert one file from each set (inner
vector) at each element in the outer map.

What I wanted was this: When the []-operator is used with a key that
does not exist in the map a new element is created using the default
constructor (and a reference to this element returned is then
returned). I was hoping for a way to use another constructor instead
of the default one (in this case vector<string>(files.size()) ).
However after some more research I see that this is not possible.

Right. You can't hope to use something that requires and uses the
default constructor, and at the same time not to use the default (and
instead use a parameterized) constructor. Mutually exclusive, you see.
You could try, however, insert a constructed vector first, and only
then access its elements using the []. IOW, take the insertion out of
the indexing operator.

V
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top