Safety of map operator[] when you dont want a default constructor

Monday, May 5, 2014

I recently ran into an interesting bug with a program at work. I would like to know a little bit more about how operator[] works with maps. Consider the following example code:



#include <map>
#include <iostream>
#include <utility>
#include <tuple>

class test
{
public:
test(int a, char b) {
a_ = a;
b_ = b;
}

void print() {
std::cout << a_ << " " << b_ << std::endl;
}

private:
int a_;
char b_;
};


int main()
{
std::map<int, test> mapper;
mapper.emplace(std::piecewise_construct,
std::forward_as_tuple<int>(1),
std::forward_as_tuple<int, char, double>(1, 'c', 2.34));
mapper[1].print();
}


The code is very simple, and the objective is pretty clear, I dont want to have a default constructor for the class test. This code wont compile however, because mapper[1].print() calls the default constructor.


The obvious solution here is to replace mapper[1].print() with mapper.find(1)->second.print(). I am just interested in why it is necessary for mapper[1] to create a test. Does this mean that every time in any code i have written with a map using operator[] that it creates a default and copies the class before calling its functions?


This seems like a huge waste of time, i understand its necessity during something like this: mapper[2] = test(1, 'a'). Is there not any way that it could tell that its not part of an operator= call? I guess not.







http://ift.tt/1lTnkL1