Boost.Any erhalten ursprünglichen Typ

8

Ich muss eine any Variable auf einen Originaltyp umwandeln. Ich muss das tun:

%Vor%

Aber ich möchte, dass der Typ in any variable speichert. Und ich schreibe das:

%Vor%

Wie kann ich so etwas machen? Oder wie kann ich den ursprünglichen Typ aus der Variable any extrahieren? Boost.variant ist auch bequem.

Wenn ich das nicht tun kann, dann habe ich eine andere Frage, was C ++ Techniken und Bibliotheken speichern können und den Typ durch eine Funktion erhalten, um dieses Problem zu lösen?

    
Kron 02.02.2012, 00:15
quelle

2 Antworten

15

C ++ ist eine statisch typisierte Sprache. Der Typ von boost::any ist ein Laufzeit -Wert; ein bestimmtes any könnte einen beliebigen Typ haben. Das ist irgendwie der Punkt.

Es gibt keine any::type_value , da dies ein Kompilierzeit Wert wäre. Und any ist ein Laufzeitkonstrukt.

Bedenken Sie Folgendes:

%Vor%

Welcher Typ ist any::type_value ? Es ist zulässig, TakeAnAny mit virtuell beliebigem -Typ aufzurufen. Es gibt keinen einzelnen Kompilierungszeittyp, auf den any::type_value reduzieren könnte. Daher gibt es keine Möglichkeit für den Compiler, einen Typ zu bestimmen. Da C ++ statisch getippt ist, bist du abgespritzt.

Der letztendliche Zweck von jedem ist Typ-Löschung. Ich habe etwas Wert. Und ich möchte das an eine andere Funktion weitergeben. Dieser Prozess wird mehrere verschiedene Kommunikationsschichten durchlaufen. Aber ich möchte nicht unbedingt, dass alle diese verschiedenen Ebenen genau wissen, welchen Typ ich verwende. Ich brauche nur mich und mein beabsichtigtes Ziel, um den Typ zu kennen. Also steckst du es in any und dir geht es gut. Alle anderen sehen nur das any , und beide wissen, was es umhüllt.

Dieser Prozess funktioniert nur, weil sowohl die Quelle als auch das Ziel den realen Typ des Werts kennen. Wenn Sie den Typ nicht kennen, sollten Sie any nicht verwenden. Der Zweck von any ist nicht eine Funktion sitzen dort und werfen es auf eine Reihe von möglichen Typen (das ist, was boost::variant ist für). Der Zweck besteht darin, den Typ aus der Signatur einer Funktion zu löschen.

Dies ermöglicht Dinge wie generische Nachrichten und Signale. Sie registrieren einen Event-Handler bei einem System. Sie feuern ein Ereignis ab, das ein any als Parameter verwendet. Die Person, die das Ereignis auslöst, weiß, dass das Ereignis "MouseClick" immer einen vec2 als Parameter verwendet. Jeder "MouseClick" -Handler wandelt es in vec2 um. Das "KeyPress" Event würde vielleicht ein int32_t übergeben. Also haben diese Handler es auf diesen Typ gewandert. Und so weiter. Jeder weiß, um welchen Typ es sich handelt.

Früher wurde das mit void* gemacht. Das Problem besteht darin, dass Sie Eigentumsprobleme haben ( any ist ein Wert, während void* ein Zeiger ist). Außerdem wird void* so gelöscht, dass es keine Möglichkeit gibt, zu überprüfen, ob Ihre Besetzung korrekt ist. any ist wirklich nur ein Typ & amp; wertsicher void* ; Es verhindert, dass Sie auf den falschen -Typ übertragen.

Sie wollen wirklich nicht any . Ihr Anwendungsfall scheint auch variant nicht zu wollen. Was Sie zu haben scheinen, ist eine Vorlage . Das ist eine andere Art von Sache, und es würde Sie tun lassen, was Sie wirklich wollen: eine Funktion haben, die einen bestimmten Typ verwenden kann, während Sie immer noch genau wissen können, um was für ein Typ es sich handelt.

Natürlich haben Vorlagen ihre eigenen Einschränkungen.

    
Nicol Bolas 02.02.2012, 00:50
quelle
1

Sie können eine Zuordnung von std::type_info zu std::function<void(boost::any const&)> object verwenden, um mit den Typen umzugehen, die Ihnen bekannt sind und mit denen Sie arbeiten möchten: Sie würden den Eintrag in der Map mit a.type() suchen und die entsprechende Funktion aufrufen was wissen würde, wie man mit dem Argument umgeht.

    
Dietmar Kühl 02.02.2012 00:26
quelle

Tags und Links