Reputation: 419
Why do I get a compile error for "recMap[key] = rec;" in the below code but the equivalent statements work fine? I have other code that does this. What simple thing am I missing?
#include <map>
class MyRec {
public:
MyRec(int numberIn) : myNumber(numberIn) { };
int myNumber;
};
int main(int argc, char **argv)
{
typedef std::map<int, MyRec> Recs;
Recs recMap;
int num=104702;
int key=100923;
MyRec rec(num);
recMap[key] = rec; // Doesn't compile
// error: no matching function for call to MyRec::MyRec()
// samp.cpp:5: note: candidates are: MyRec::MyRec(int)
// samp.cpp:3: note: MyRec::MyRec(const MyRec&)
// Why do I receive the compile error for the above if it is the same as:
(*((recMap.insert(std::make_pair(key,rec))).first)).second;
recMap.insert(std::pair<int, MyRec>(key,rec)); // Works also of course
}
Upvotes: 2
Views: 790
Reputation: 2754
In your code, you mention that you expect the [] operator
to work the same as:
(*((recMap.insert(std::make_pair(key,rec))).first)).second;
But it is not the same as that statement; rather it's the same as:
(*((recMap.insert(std::make_pair(key,MyRec()))).first)).second;
Written like this, hopefully it's easier to see why the code doesn't compile (that is, MyRec does not define a parameter-less constructor).
Upvotes: 0
Reputation: 11502
Consider this snippet:
std::map<int, Foo> map;
map[0];
This will actually work fine even if havent inserted an object for key 0. The reason is, that there is a difference between std::map::at()
and std::map::operator []()
:
std::map::at()
only returns a reference to an object inside the map. If there isnt an object for the given key, an exception is thrown.
std::map::operator []()
does also return a reference, however if there no object for the given key, it creates an object inside the map and returns a reference to this newly created object. In order to create the object std::map
must call the default constructor (a constructor with no additional arguments).
That is the reason why you code wont compile: Your class MyRec
is not default constructable, but std::map::operator []
requires this.
Thus you have three options:
std::map::insert()
std::map::emplace()
MyRec
default constructable.Upvotes: 5