2010-06-17 10 views
7

Wie kann ich meine eigenen Klassenobjekte in ptr_map von Boost einfügen. Die Objekte sind Vorlagen, so dass ich keinen statischen Typnamen in der Map verwenden kann. Also habe ich:Boost jede Verwendung

ptr_map<string, any> someMap; 

Meine Klasse erbt die boost :: noncopyable.

someMap.insert("Test", new MyClass<SomeTemplate>()); 

Der Fehler ist: Fehler: no matching function for call to ‘boost::ptr_map.


UPD: ich lieber etwas Wrapper machen und verwenden Sie nicht die boost :: any. Also:

class IWrapper { }; 
class MyClass : public IWrapper { }; 

ptr_map<string, IWrapper> someMap; 
someMap.insert("Test", new MyClass<SomeTemplate>()); 

Warum wird es nicht funktionieren (der gleiche Fehler)? Ich könnte die geerbte Klasse in die Elternschnittstelle übergeben. Was ist los mit dir?

Antwort

3

Bei weitem die meisten Probleme dieser Art sollten mit einer gemeinsamen Basisklasse gelöst werden. Dies ist der Fall, wenn alle Klassen ähnlich verwendet werden. Laufzeitpolymorphismus.

Ich habe legitime Gründe gesehen, eine gemeinsame Basisklasse nicht zuzulassen. In diesem Fall wird boost::variant Server in der Regel besser, da es noch Methoden gibt, um jeden Artikel einheitlich zu behandeln (ein Besucher). Kompiliere Zeitpolymorphie.

Ich habe nie eine legitime Verwendung für boost::any gesehen. Ich sage nicht, dass es keins gibt, aber es ist so selten, dass ich es noch nie gesehen habe.


Das sagte, versuchen Sie dies.

std::map<std::string,boost::any> someMap; 
boost::any insanity = new MyClass<SomeTemplate>; 
someMap.insert("Test",insanity); 

oder

boost::ptr_map<std::string,boost::any> someMap; 
boost::any* ive_lost_it = new boost::any(new MyClass<SomeTemplate>); 
someMap.insert("Test", ive_lost_it); 
+0

Meine Klassen sind templated. Ich habe das Beispiel aktualisiert. Ich kann keine Basis dafür bilden (ohne Vorlage). – Ockonal

+0

Okay, danke. Der Weg mit jedem sollte funktionieren. Aber könnten Sie sich ein neues Code-Update ansehen? Ich habe versucht deine erste Idee zu verwirklichen. – Ockonal

1

Zuerst Sie jede * zu Ihrer ptr_map bereitstellen muss.
Dann muss der Schlüssel ein Lvalue sein (aufgrund von Ausnahmesicherheitsproblemen).

boost::ptr_map<std::string, any> someMap; 
any * p = new any(MyClass<Sometype>); 
std::string test = "test"; 
someMap.insert(test, p); 

- bearbeiten
Das Gleiche gilt, wenn Sie eine Wrapper-Klasse verwenden. Der Schlüssel muss ein Lvalue sein.

Übrigens ist das Problem mit der Wrapper/Basisklasse hier, dass Sie nicht in der Lage sein werden, zum ursprünglichen Typ zurückzukehren (und Sie haben keinen dynamischen Polymorphismus entweder wegen des Schablonentyps).

+0

Was bedeutet "Lvalue"? Können Sie eine Probe zeigen? – Ockonal

+0

Lvalue bedeutet zuweisbar (und nicht const). "test" ist nicht zuweisbar und const, std :: string test ist jedoch ein Lvalue. – log0