Here is the approximate code of my question. First, we have a struct with a constructor:
struct Pair{
Pair(int a, int b): (first (a) , second (b) ) {}
int first;
int second;
};
which is used in a map
map<string, Pair> mymap;
I would like to initialize this map in a function
void f(map<string, Pair>* mymap, string c,int x, int y )
{
(*mymap)[c]=Pair(x,y);
}
But the compiler says first that it could not find an appropriate constructor and then the next lines are that not enough arguments are provided for the constructor.
A friend of mine told me that I should write the function like this:
void f(map<string, Pair>& mymap, const string& c,int x, int y )
{
if (mymap.find(c) != mymap.end()) {
mymap[c] = Pair(x,y);
}
}
But he could not explain why Type& should be used here instead of Type *, and I would like to clarify this point. Can anybody explain?
The problem is that
operator[]in a map requires that the value type is default constructible. If you don’t want yourPairto be default constructible, you will have to avoid usingoperator[]:You may have misunderstood what your friend suggested. The problem with
operator[]is not that it requires the default constructor if it needs to create a new element, but that it requires it in case it might need to. That is, whether the element exists before hand or not does not really matter.If you also mean to update, then you need to consider also that option:
Basically the
insertoperation returns a pair of the iterator pointing at the key and a bool indicating if thisinsertcreated the object or if it was already there (in which case the value in the map is unmodified). By storing the result, we can test and if theinsertdid not create the value, we can update it through the returned iterator.