tags:

views:

1340

answers:

5

See also http://stackoverflow.com/questions/695372/c-standard-list-and-default-constructible-types

Not a major issue, just annoying as I don't want my class to ever be instantiated without the particular arguments.

class MyClass
{
public:
    MyClass(MyType1 t);
    MyType2 &operator[](int index);
}

map<int, MyClass> myMap;

This gives me the following g++ error:

/usr/include/c++/4.3/bits/stl_map.h:419: error: no matching function for call to ‘MyClass()’

This compiles fine if I add a default constructor; I am certain it's not caused by incorrect syntax.

+6  A: 
Assaf Lavie
Do you think bb could be on to something regarding [] operator?
nbolton
+1  A: 

Check if:

  • You forgot the ';' after class declaration.
  • MyType should've been declared accordingly.
  • No default constructor there...

The std::map declaration seems correct, I think.

Hernán
Compiles fine if I add a default constructor.
nbolton
+1  A: 

Most likely because std::pair requires it. std::pair holds two values using value semantics so you need to be able to instantiate them without parameters. So the code uses std::pair in various places to return the map values to the caller and this is commonly done by instantiating an empty pair and assigning the values into it before returning the local pair.

You could get around this with smart pointers using a map<int, smartptr<MyClass> > but that adds the overhead of checking for null pointers.

jmucchiello
+1 nice tip about smartptr
nbolton
+0. pair<T, U> can be used just fine with types T and U lacking default constructors -- the only thing that cannot be used in this case is pair<T, U>'s own default constructor. No decent-quality implementation of map<K, V> would use this default constructor because it limits what K and V can be.
j_random_hacker
+18  A: 

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 object data_type().

If you don't have default constructor you could use insert/find functions. Next exaple will works:

myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) );
myMap.find( 1 )->second;
bb
+1 Good point about [].
nbolton
A: 

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.

oo_olo_oo