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
test(int a, char b) {
a_ = a;
b_ = b;

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

int a_;
char b_;

int main()
std::map<int, test> mapper;
std::forward_as_tuple<int, char, double>(1, 'c', 2.34));

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.