2010-08-23 7 views
7

Ich arbeite immer noch an einer guten Lösung für meine One-Of-A-Type Container Problem - und nach der Reflektion denke ich, es wäre schön, in der Lage zu sein, etwas wie eine std::map<std::type_info, boost::any> zu verwenden. Leider definiert std::type_info keinen operator<, und ich denke, es wäre unvernünftig, einen zu definieren.Bietet C++ 11 Hashfunktionen für std :: type_info?

Es scheint jedoch vernünftig, eine Hash-Funktion für sie zu definieren, weil Sie einfach die Singleton-Adresse des std::type_info Objekts als einen vernünftigen "Hash" verwenden können. Daher könnten Sie eine std::type_info in eine std::unordered_map als Schlüssel setzen.

Bietet C++ 11 eine solche Hash-Funktion? Würde die Verwendung der Speicheradresse des Singletons std::type_info eine schlechte Hash-Strategie sein?

+2

Es ist übrigens kein Singleton, sondern ein statisch zugewiesenes Objekt. – GManNickG

+0

@GMan: Was ist der Unterschied? –

+1

Wenn es ein Singleton wäre, gäbe es genau ein "type_info" -Objekt. Da es in einem Programm mehrere Typen gibt, muss es mehr als ein 'type_info'-Objekt im Programm geben. –

Antwort

9

Die Tatsache, dass type_info ist nicht weniger als vergleichbar ist nicht so sehr ein Problem für die Verwendung als ein Kartenschlüssel als die Tatsache, dass type_info ist nicht kopierbar. :-)

In C++ 03, type_info hat eine before() Mitgliedsfunktion, die eine Bestellung von type_info Objekte bereitstellt.

In 11 C++ hat type_info einen hash_code() Memberfunktion (C++ 11 §18.7.1/7):

size_t hash_code() const throw(); 

Returns: eine unspezifische ed, ausgenommen, dass innerhalb eines einzelne Ausführung des Programms, es soll den gleichen Wert für zwei type_info Objekte, die gleich sind, zurückgeben.

Bemerkung: eine Implementierung sollte verschiedene Werte für zwei type_info Objekte zurückgeben, die nicht gleich vergleichen.

type_info Objekte aus dem typeid Teilnehmer bestehen bis zum Ende des Programms, so ist es sicher ein type_info* als Kartenschlüssel zu verwenden. Nach meinem besten Wissen gibt es keine Garantie, dass wenn Sie typeid auf zwei Objekte des gleichen Typs anwenden, erhalten Sie zwei Referenzen auf das gleiche type_info Objekt.

Wenn Sie type_info* als Mapkey tun verwenden, würde ich einen benutzerdefinierten Komparator verwenden, die die Zeiger dereferenziert und vergleicht die type_info Objekte selbst (unter Verwendung der oben genannten before() oder hash_code() für die Bestellung).

+0

@James: D'oh! Vielleicht kann ich 'std :: type_info *' verwenden (weil es nur eine Instanz einer bestimmten type_info-Klasse gibt?)? –

+0

@Billy: Das sollte sicher sein (siehe meine Bearbeitung für Vorbehalte). –

+0

@James: Das könnte schwierig sein, da 'std :: type_info' Objekte keinen effizienten Vergleich bieten. Es sieht so aus, als wäre es für mich die Lösung für die Hausbrauerei:/ –

10

Sie könnten auch type_index verwenden, es enthält sicher einen Zeiger auf eine type_info, es ist kopierbar, vergleichbar und eine Hash-Funktion ist für Standard-Container zur Verfügung gestellt.

Verwandte Themen