¿Por qué el argumento del tipo de mapa C ++ requiere un constructor vacío cuando se usa ?

Ver también la lista estándar de C ++ y los tipos construibles por defecto

No es un problema importante, solo molesto ya que no quiero que mi clase sea instanciada alguna vez sin los argumentos particulares.

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

Esto me da el siguiente error de g ++:

/usr/include/c++/4.3/bits/stl_map.h:419: error: sin función de coincidencia para la llamada a ‘MyClass ()’

Esto comstack bien si agrego un constructor predeterminado; Estoy seguro de que no se debe a una syntax incorrecta.

Este problema viene con el operador []. Cita de la documentación de SGI:

data_type& operator[](const key_type& k) – Devuelve una referencia al objeto que está asociado con una tecla en particular. Si el mapa aún no contiene dicho objeto, el operator[] inserta el objeto predeterminado data_type() .

Si no tiene un constructor predeterminado, puede usar las funciones de inserción / búsqueda. El siguiente ejemplo funciona bien:

 myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) ); myMap.find( 1 )->second; 

Sí. Los valores en los contenedores STL necesitan mantener la semántica de copia. IOW, necesitan comportarse como tipos primitivos (por ejemplo, int) lo que significa, entre otras cosas, que deben ser predecibles.

Sin esto (y otros requisitos) sería innecesariamente difícil implementar las diversas operaciones internas de copiar / mover / intercambiar / comparar en las estructuras de datos con las que se implementan los contenedores STL.

Al hacer referencia al Estándar C ++, veo que mi respuesta no era precisa. La construcción predeterminada no es, de hecho, un requisito :

Desde 20.1.4.1:

El constructor predeterminado no es requerido. Ciertas firmas de función miembro de clase de contenedor especifican el constructor predeterminado como un argumento predeterminado. T () debe ser una expresión bien definida …

Así que, estrictamente hablando, su tipo de valor solo debe ser predecible y construible si está utilizando una función del contenedor que usa el constructor predeterminado en su firma.

Los requisitos reales (23.1.3) de todos los valores almacenados en contenedores STL son CopyConstructible y Assignable .

También existen otros requisitos específicos para contenedores particulares, como ser Comparable (por ejemplo, para claves en un mapa).


Por cierto, lo siguiente comstack sin error en comeau :

 #include  class MyClass { public: MyClass(int t); }; int main() { std::map myMap; } 

Entonces esto podría ser un problema de g ++.

Verifique los requisitos del tipo almacenado de stl :: map. Muchas colecciones stl requieren que el tipo almacenado contenga algunas propiedades específicas (constructor predeterminado, constructor de copia, etc.).

El stl :: map necesita un constructor sin argumentos, porque se usa cuando el operador [] se invoca con la clave, que el mapa no ha conservado. En este caso, el operador [] inserta la nueva entrada que consiste en la nueva clave y el valor construido usando un constructor sin parámetros. Y este nuevo valor es devuelto.

Comprobar si:

  • Olvidaste el ‘;’ después de la statement de clase.
  • MyType debería haberse declarado en consecuencia.
  • No hay constructor predeterminado allí …

La statement de std :: map parece correcta, creo.

Probablemente porque std :: pair lo requiere. std :: pair contiene dos valores usando la semántica de valores, por lo que debe poder crear instancias sin parámetros. Entonces, el código usa std :: pair en varios lugares para devolver los valores del mapa a la persona que llama, y ​​esto se hace comúnmente instanciando un par vacío y asignándole los valores antes de devolver el par local.

Podría solucionar esto con punteros inteligentes utilizando un mapa > pero eso agrega la sobrecarga de buscar punteros nulos.