Ich versuche eine Konvertierungsfunktion zwischen Objekten zweier Klassen (Eigen :: Vector3d und MyVector, eine Protocol Buffers Nachricht) zu erstellen, aber ich möchte die Auswertung des Funktionskörpers verzögern, bis die Funktion referenziert ist (an diesem Punkt beide Klassen würden definiert werden).
Die Funktion sollte in Dateien aufrufbar sein, die später beide Klassen definieren, und sollte keinen Kompilierungsfehler verursachen, wenn die Funktion nie verwendet wird.
Ich habe:
%Vor%was ich benutze als:
%Vor%Das funktioniert gut, wenn die Funktion nach MyVector definiert ist, aber ich möchte die Funktion so definieren können, dass sie in eine Übersetzungseinheit aufgenommen werden kann, der die MyVector-Klasse fehlt.
Ich könnte die Funktion ändern:
%Vor%Dies ist jedoch inakzeptabel, da es für andere Nachrichtenklassen gelten würde:
%Vor%und ich möchte, dass das einen Buildfehler verursacht.
Gibt es eine Art Template-Magie, die das kann? Wenn nicht, gibt es eine bessere Möglichkeit, diesen Operator kurz vor dem Hinzufügen von MyVector zur Headerdatei (oder seinen Abhängigkeiten) zu stellen?
Sie können undefinierte Typen oder Funktionen in Funktionsschablonen verwenden, solange sie irgendwie von einem Template-Argument abhängen und zum Zeitpunkt der Instantiierung definiert sind: Nicht-abhängige Namen werden an dem Zeiger nachgeschlagen, an dem die Funktionsvorlage definiert ist. Abhängige Namen werden an der Stelle der Instanziierung nachgeschlagen (angenommen, dass die Zweiphasen-Namenssuche korrekt implementiert ist).
Die andere Seite, die eine erfolgreiche Instanziierung mit anderen Typen als einem kleinen Satz ausgewählter Typen verhindert, könnte wahrscheinlich mit SFINAE erfolgen :
%Vor% type
von std::enable_if<F, T>
ist nur definiert, wenn F
ist true
(und T
ist standardmäßig void
). Da std::is_same<Msg, MyVector>::value
erst dann true
wird, wenn Msg
ist MyVector
Dieser Operator wird nur definiert, wenn er mit MyVector
instanziiert wird. Auf der anderen Seite wird es definiert, wenn ein Punkt MyVector
hoffentlich instanziiert wird.
Da jedoch MyVector
in der Schnittstelle benannt wird, muss dessen Name deklariert werden, obwohl er nicht definiert werden muss. Es ist möglich, diese Notwendigkeit zu vermeiden, wenn MyVector
eine Eigenschaft spezialisieren könnte. In diesem Fall kann die Angabe von MyVector
a type verzögert werden, bis sie definiert ist und die Eigenschaft stattdessen spezialisiert ist. Dies kann wichtig sein, wenn MyVector
tatsächlich eine Vorlage mit default-Argumenten ist, da diese nicht vorwärts deklariert werden können.
Erstellen Sie eine kleine templatierte Klasse, die spezialisiert ist und verwenden Sie diese im template-Operator & lt; & lt; Funktion.
ie:
%Vor%Sie können dieses Muster bei Bedarf auf weitere Vorlagenparameter erweitern und nur für die gewünschten Konvertierungen spezialisieren.
Tags und Links c++