0

As I create a std::map, all the indexes are initially pointing nowhere. As soon as I call them, they allocated and assigned the value 0.

For example:

map <int, int> x;
cout << x.[31233];

The output is 0.

However, I need that all the standard assigned value to be (-1) instead of 0.

How can I change this?

Charles
  • 50,943
  • 13
  • 104
  • 142
  • 2
    You can't not by using standard types like `int` for the data anyway. You *could* possibly create a class that can be implicitly converted to an `int` and whose constructor sets the value to `-1` on construction. – Some programmer dude Mar 05 '14 at 12:50
  • Welcome to Stack Overflow. "Thank you" and "Hello" are usually omitted here, it's all about the raw question. – lethal-guitar Mar 05 '14 at 12:51
  • `std::map<>::operator[]` auto-inserts and value-initializes the value for a key if it wasn't present in the map. (and `int()` is zero). If you want something different, you likely need to `find(key)` the key, and if the resulting iterator is `x.end()`, `insert` it with (-1) for the value. – WhozCraig Mar 05 '14 at 12:51
  • 1
    @JoachimPileborg well, in theory you could write a custom allocator which initializes to `-1`.. But why would you want to do that ;) – lethal-guitar Mar 05 '14 at 12:54
  • 1
    @lethal-guitar because you *can* ? =P – WhozCraig Mar 05 '14 at 13:00

3 Answers3

2

After this definition

map <int, int> x;

the map has no elements. To add an element with key 31233 and value -1 you can write

x[31233] = -1;

You can not do such a way that the default value would be -1 because according to the C++ Standard relative to the subscript operator

If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map

For type int int() zero initializes the corresponding object.

Otherwise you should use some insert method where you will explicitly specify an initial value.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Given a std::map<key_type, value_type>, a lookup for an arbitrary key through operator [](cont key_type&) will auto-insert value_type() for said-key if it wasn't present. In your case, value_type is int, and int() is zero-initialized, therefore zero is the result.

if you want to use a different default construct, you have options, the most extreme of which would be writing a custom allocator specialized for int and a construct member to us -1 for int value types (yuck). I think you may find it easier to simply:

std::map <int, int> x;

// load map with values...

int res = -1;
auto it = x.find(31233);
if (it != x.end())
    res = x.second;

// use res here.
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • The allocator thing won't work: see [this comment](http://stackoverflow.com/questions/2333728/stdmap-default-value#comment2316284_2333786). – interjay Mar 05 '14 at 13:11
  • @interjay I swear I've done it, but I probably broke the rules in doing so. One *could* do something utterly dreadful and just spin an `Integer` class with a boatload of overloads and a default construct of (-1) rather than 0, then map int-to-Integer. talk about yuck. – WhozCraig Mar 05 '14 at 13:25
0

You should simply stop using the operator[] and instead use insert() when you intend to insert a new value. If you want to have a "default" value for things that have never been inserted, it may be better to write your own container which uses a map internally and exposes something like a get() method which returns the stored value from the map or -1 if not found. That way you avoid storing lots of -1 values that aren't needed.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436