tags:

views:

69

answers:

5

Hi,

I have a std::map, and I would like to add a valid key to iterate over it later, but without giving any value (it will be given later on in the course of the iterations).

This is how I do it for now :

std::vector<std::string> valid_keys;
//Fill... Then :
std::map<std::string, float> map;
for(size_t i = 0 ; i < valid_keys.size() ; ++i) {
    /*I don't want to do that because in fact I don't use a float type*/ 
    map[valid_keys[i]] = 0.f; //<- 
}
//Using :
for(std::map<std::string, float>::iterator it = map.begin() ; it != map.end() ; ++it) {
    it->second = 0; //Dummy
}

How can I do that, please ?

Thanks aforehand.

+1  A: 

std::map stores pairs of items. You cannot add a key without an associated value.

Binary Worrier
+5  A: 

I'm not entirely sure what you mean by "without giving any value" but if you mean without explicitly assigning a value then just do

map[valid_keys[i]];

This still works i.e. it creates a new entry in the map if there was not previously one with that key. The operator[] just returns a refernce to the value so that you can assign a new value to it but remember it's already been default constructed.

If, on the other hand, you mean you want to express that there is no meaningful value and it may or may not subsequently receive a valid value then see @UncleBens` answer.

Troubadour
+1: Probably what the asker was looking for, I couldn't make sense of the question THB.
Binary Worrier
I didn't even think of that (shame on me), thanks !@Binary worrier : sorry for the question, I should have reformulated.
Mister Mystère
@Mister: `map[key];` is equivalent to `map[key] = value_type();`. In your example, that would be `map["key"]=float();`. Replace `float` with any other type (that has a default constructor).
sbi
+4  A: 

I suppose something that could help you out is Boost.Optional.

#include <boost/optional.hpp>
#include <map>

class CantConstructMe
{
    CantConstructMe() {}
};

int main()
{
    std::map<int, boost::optional<CantConstructMe> > m;
    m[0];
}

The lack of available default constructor is not an issue, by default optional will be empty.

UncleBens
+1 - I actually think THIS is what the OP is looking for.
Noah Roberts
A: 

/* I don't want to do that because in fact I don't use a float type */

Then instead of std::map use the std::set.

Dummy00001
A: 

It seems like you really want a std::set or std::list of keys, and then iterate over that set later to create your map.

If for some reason this isn't acceptable, you could wrap your float with some type of object that implements operator float(), and various conversion functions for float, but also has a "good()" flag or somesuch.

If your final values are actually floats, you could initialize the values to +/- NaN as a simple placeholder.

I would say boost::optional is a better option for production code, but it depends on your requirements.

jkerian