Voir aussi http://stackoverflow.com/questions/695372/c-standard-list-and-default-constructible-types
Pas un problème majeur, juste ennuyeux que je ne veux pas que ma classe à être instancié sans les arguments particuliers.
class MyClass { public: MyClass(MyType1 t); MyType2 &operator[](int index); } map<int, MyClass> myMap;
Cela me donne la suite de g++ erreur:
/usr/include/c++/4.3/bits/stl_map.h:419: error: no matching function for call to ‘MyClass()'
Cette compile très bien si j'ajoute un constructeur par défaut; je suis certain que ce n'est pas causée par une syntaxe incorrecte.
Réponses
Trop de publicités?Ce problème vient avec l'opérateur []. Extrait de la documentation SGI:
data_type& operator[](const key_type& k)
- Renvoie une référence à l'objet associé à une clé particulière. Si la carte ne contient pas déjà un tel objet,operator[]
insère l'objet par défautdata_type()
.
Si vous n'avez pas de constructeur par défaut, vous pouvez utiliser des fonctions insert / find. L'exemple suivant fonctionnera:
myMap.insert( std::map< int, MyClass >::value_type ( 1, MyClass(1) ) );
myMap.find( 1 )->second;
Oui. Les valeurs dans des conteneurs STL nécessité de maintenir la sémantique de copie. OIE, il faut qu'ils se comportent comme des types primitifs (ex int), ce qui signifie, entre autres choses, ils doivent être par défaut constructible.
Sans cela (et d'autres exigences), il serait inutilement difficile à mettre en œuvre les différents interne copier/déplacer/swap/comparer les opérations sur les structures de données avec laquelle les conteneurs STL sont mis en œuvre.
Lors de la référence à la Norme C++, je vois que ma réponse n'était pas exacte. Par défaut-la construction est, en fait, pas une obligation:
De 20.1.4.1:
Le constructeur par défaut n'est pas nécessaire. Certaines classe de conteneur membre des signatures de fonction spécifier l' constructeur par défaut comme valeur par défaut argument. T() doit être bien défini expression ...
Donc, à strictement parler, de votre type de valeur ne doit être par défaut constructible si vous arrive d'être en utilisant une fonction de contenant qui utilise le constructeur par défaut dans sa signature.
Les besoins réels (23.1.3) à partir de toutes les valeurs stockées dans des conteneurs STL sont CopyConstructible
et Assignable
.
Il y a aussi d'autres exigences spécifiques pour notamment les conteneurs ainsi, comme Comparable
(par exemple pour les clés dans un plan).
D'ailleurs, la suite se compile sans erreur sur comeau:
#include <map>
class MyClass
{
public:
MyClass(int t);
};
int main()
{
std::map<int, MyClass> myMap;
}
Donc cela pourrait être un g++ problème.
Exigences en matière de vérification de l'stockés type de la stl::map. De nombreux stl collection exiger que stockées type contient certaines propriétés spécifiques (par défaut constructeur, constructeur de copie, etc.).
Constructeur sans arguments est nécessaire par la stl::map, parce qu'il est utilisé, lorsque l'opérateur[] est appelé avec la clé, ce qui n'a pas déjà été conservé par la carte. Dans ce cas, l'opérateur[] insère la nouvelle entrée composé de la nouvelle clé et la valeur construite à l'aide de constructeur sans paramètre. Et cette nouvelle valeur est alors retourné.
Probablement parce que std::pair exige. std::pair a deux valeurs à l'aide de la valeur sémantique de sorte que vous devez être en mesure de les instancier sans paramètres. Si le code utilise des std::pair dans différents lieux pour retourner les valeurs de la carte de l'appelant et cela se fait couramment par l'instanciation d'un vide de la paire et de l'affectation de valeurs en avant de retourner le local paire.
Vous pourriez obtenir autour de cette avec des pointeurs intelligents à l'aide d'une map<int, smartptr<Maclasse> > mais qui ajoute les frais généraux de la vérification des pointeurs null.