Siehe auch C ++ - Standardliste und standardmäßig konstruierbare Typen
Kein großes Problem, nur ärgerlich, da ich nicht möchte, dass meine Klasse jemals ohne die besonderen Argumente instanziiert wird.
#include <map>
struct MyClass
{
MyClass(int t);
};
int main() {
std::map<int, MyClass> myMap;
myMap[14] = MyClass(42);
}
Dies gibt mir den folgenden g ++ Fehler:
/usr/include/c++/4.3/bits/stl_map.h:419: Fehler: Keine passende Funktion für den Aufruf von 'MyClass ()'
Dies lässt sich gut kompilieren, wenn ich einen Standardkonstruktor hinzufüge. Ich bin sicher, dass es nicht durch falsche Syntax verursacht wird.
c++
dictionary
Nick Bolton
quelle
quelle
Antworten:
Dieses Problem tritt mit operator [] auf. Zitat aus der SGI-Dokumentation:
Wenn Sie keinen Standardkonstruktor haben, können Sie Einfüge- / Suchfunktionen verwenden. Das folgende Beispiel funktioniert einwandfrei:
quelle
emplace
in C ++ 11 als knappe Alternative zu beachteninsert
.std::<map>::value_type
dort iminsert
Anruf?= default
sollte gut funktionieren.Ja. Werte in STL-Containern müssen die Kopiersemantik beibehalten. IOW, sie müssen sich wie primitive Typen (z. B. int) verhalten, was unter anderem bedeutet, dass sie standardmäßig konstruierbar sein sollten.Ohne diese (und andere Anforderungen) wäre es unnötig schwierig, die verschiedenen internen Operationen zum Kopieren / Verschieben / Austauschen / Vergleichen in den Datenstrukturen zu implementieren, mit denen STL-Container implementiert sind.Unter Bezugnahme auf den C ++ - Standard sehe ich, dass meine Antwort nicht korrekt war. Die Standardkonstruktion ist in der Tat keine Voraussetzung :
Ab 20.1.4.1:
Genau genommen muss Ihr Wertetyp nur dann standardmäßig konstruierbar sein, wenn Sie zufällig eine Funktion des Containers verwenden, der den Standardkonstruktor in seiner Signatur verwendet.
Die tatsächlichen Anforderungen (23.1.3) an alle in STL-Containern gespeicherten Werte sind
CopyConstructible
undAssignable
.Es gibt auch andere spezifische Anforderungen für bestimmte Container, z. B.
Comparable
(z. B. für Schlüssel in einer Karte).Übrigens wird folgendes auf comeau fehlerfrei kompiliert :
Dies könnte also ein G ++ - Problem sein.
quelle
Überprüfen Sie die Anforderungen des gespeicherten Typs der stl :: map. Viele stl-Auflistungen erfordern, dass der gespeicherte Typ einige spezifische Eigenschaften enthält (Standardkonstruktor, Kopierkonstruktor usw.).
Der Konstruktor ohne Argumente wird von der stl :: map benötigt, da er verwendet wird, wenn operator [] mit dem Schlüssel aufgerufen wird, der noch nicht von der Map beibehalten wurde. In diesem Fall fügt der Operator [] den neuen Eintrag ein, der aus dem neuen Schlüssel und dem Wert besteht, die mit dem parameterlosen Konstruktor erstellt wurden. Und dieser neue Wert wird dann zurückgegeben.
quelle
Überprüfen Sie, ob:
Die std :: map-Deklaration scheint korrekt zu sein, denke ich.
quelle
Höchstwahrscheinlich, weil std :: pair dies erfordert. std :: pair enthält zwei Werte unter Verwendung der Wertesemantik, sodass Sie sie ohne Parameter instanziieren können müssen. Daher verwendet der Code an verschiedenen Stellen std :: pair, um die Kartenwerte an den Aufrufer zurückzugeben. Dies geschieht normalerweise, indem ein leeres Paar instanziiert und die Werte zugewiesen werden, bevor das lokale Paar zurückgegeben wird.
Sie könnten dies mit intelligenten Zeigern umgehen, indem Sie eine Karte <int, smartptr <MyClass>> verwenden. Dies erhöht jedoch den Aufwand für die Suche nach Nullzeigern.
quelle