Why does the C++ map type argument require an empty constructor when using []?
Solution 1:
This issue comes with operator[]. Quote from SGI documentation:
data_type& operator[](const key_type& k)
- Returns a reference to the object that is associated with a particular key. If the map does not already contain such an object,operator[]
inserts the default objectdata_type()
.
If you don't have default constructor you can use insert/find functions. Following example works fine:
myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) );
myMap.find( 1 )->second;
Solution 2:
Yes. Values in STL containers need to maintain copy semantics. IOW, they need to behave like primitive types (e.g. int) which means, among other things, they should be default-constructible.
Without this (and others requirements) it would be needlessly hard to implement the various internal copy/move/swap/compare operations on the data structures with which STL containers are implemented.
Upon reference to the C++ Standard, I see my answer was not accurate. Default-construction is, in fact, not a requirement:
From 20.1.4.1:
The default constructor is not required. Certain container class member function signatures specify the default constructor as a default argument. T() must be a well-defined expression ...
So, strictly speaking, your value type only needs to be default constructible if you happen to be using a function of the container that uses the default constructor in its signature.
The real requirements (23.1.3) from all values stored in STL containers are CopyConstructible
and Assignable
.
There are also other specific requirements for particular containers as well, such as being Comparable
(e.g. for keys in a map).
Incidentally, the following compiles with no error on comeau:
#include <map>
class MyClass
{
public:
MyClass(int t);
};
int main()
{
std::map<int, MyClass> myMap;
}
So this might be a g++ problem.
Solution 3:
Check requirements of stored type of the stl::map. Many stl collection require that stored type contains some specific properties (default constructor, copy constructor, etc.).
Constructor without arguments is needed by the stl::map, because it's used, when operator[] is invoked with the key, which hasn't already been kept by the map. In this case the operator[] inserts the new entry consisting of the new key and value constructed using parameterless constructor. And this new value is then returned.