Wissen über Originaltypen ableiten und gleichzeitig weiterleiten

8

Zusammenfassung: Ich möchte mit einer Funktion enden, die die exakten Typen ableitet, mit denen sie aufgerufen wurde, und nimmt (zB) ein Tupel, das sie weiterleitet (deren Typen sich von den exakten unterscheiden) Typen, mit denen die Funktion aufgerufen wurde).

Ich bleibe stecken und versuche, die Arten der Argumente für eine gegebene Funktion über den Abzug zu "wissen", während ich sie gleichzeitig weiterleite. Ich denke, dass mir etwas Entscheidendes fehlt, wie das funktioniert.

%Vor%

Was ich gerne sehen möchte, ist ein Szenario, in dem meine Funktion (zB g1 oder g2 ) aufgerufen wird und beide Originaltypen kennt und verwendet - int,double,void*,std::string&,const char* und die Weiterleitungen auch.

In diesem Fall scheint ich diese Informationen nicht innerhalb von g1 oder g2 zu finden. Der (absichtliche, zum Ausdrucken der Typen) Linker Fehler zeigt mir in g1 das sind:

%Vor%

und in g2 :

%Vor%

Es gibt zwei Dinge, die ich hier nicht verstehe:

  1. Warum stimmt keiner der gedruckten (über den Linker-Fehler) Typen mit dem überein, was ich tatsächlich übergeben habe? (%Code%). Kann ich ableiten, was ich tatsächlich bestanden habe? Vorzugsweise mit "natürlicher" Syntax, d. H. Alles nur einmal und nichts explizit ausgeschrieben. Ich kann explizit schreiben:

    %Vor%

    aber das ist "unhandlich" um es gelinde auszudrücken!

  2. In int,double,void*,std::string&,const char Das Vorhandensein von g1 in der Funktionssignaturdeklaration scheint die Typen im Vorlagenparameter && selbst zu ändern. Vergleichen Sie das mit:

    %Vor%

    Oder:

    %Vor%

    Verwenden Sie eines der folgenden mit:

    %Vor%

    ändert nicht den Typ von Args . Warum ändert der T den Typ von && selbst, wenn T nicht?

Flexo 25.10.2011, 13:43
quelle

2 Antworten

2

Beantworten Sie die erste Frage:

Argumente für Funktionen sind Ausdrücke , nicht Typen . Der Unterschied zwischen diesen beiden wird in Kapitel 5 [Ausdruck], p5:

ausgedrückt
  

Wenn ein Ausdruck anfänglich den Typ "Verweis auf T" hat (8.3.2,   8.5.3), der Typ wird vor jeder weiteren Analyse auf T eingestellt.

Somit gibt es keinen Unterschied zwischen g(str) und g(sref) . g() sieht immer eine std::string und niemals eine Referenz.

Zusätzlich können Ausdrücke lvalue oder rvalue sein (eigentlich ist das eine Vereinfachung der C ++ 11-Regeln, aber es ist nah genug für diese Diskussion - wenn Sie die Details haben wollen, sind sie in 3.10 [basic.lval]) / p>

Beantworten Sie die zweite Frage:

Template-Parameter des Formulars:

%Vor%

sind etwas Besonderes. Sie sind im Gegensatz zu T , T& oder sogar const T&& folgendermaßen:

Wenn T&& an einen Lvalue bindet, wird T als Lvalue-Referenztyp abgeleitet, andernfalls wird T genau nach den normalen Deduktionsregeln abgeleitet.

Beispiele:

%Vor%

Dieses Verhalten unterstützt die sogenannte perfekte Weiterleitung , die normalerweise folgendermaßen aussieht:

%Vor%

Wenn man foo(A()) (ein rvalue A ) aufruft, wird T nach normalen Regeln als A abgeleitet. Innerhalb von foo wird t in A&& (ein rvalue) umgewandelt und bar aufgerufen. Die Überladung von bar , die einen rvalue A annimmt, wird dann gewählt. I.e. Wenn wir foo mit einem rvalue aufrufen, ruft foo bar mit einem rvalue auf.

Aber wenn wir foo(a) (ein lvalue A ) aufrufen, wird T als A& abgeleitet. Jetzt sieht die Besetzung wie folgt aus:

%Vor%

was unter den Referenz-Kollabierungsregeln vereinfacht zu:

%Vor%

i.e. Der L-Wert t wird in einen L-Wert (eine No-Op-Umwandlung) umgewandelt, und somit wird die bar -Überladung, die einen L-Wert annimmt, aufgerufen. I.e. Wenn wir foo mit einem Lvalue aufrufen, ruft foo bar mit einem Lvalue auf. Und genau hier kommt der Begriff perfekte Weiterleitung .

    
Howard Hinnant 25.10.2011, 15:42
quelle
0

Typen (auch in C ++) sind meistens ein Kompilierungstyp (außer natürlich die RTTI in VTables).

Wenn Sie vollständig dynamische Typen benötigen, ist C ++ möglicherweise nicht die beste Sprache dafür.

Sie könnten GCC (eigentlich g++ , vorausgesetzt es ist mindestens 4.6) mit einem Plugin oder einem erweitern GCC MELT Erweiterung (MELT ist eine domänenspezifische High-Level-Sprache, um GCC zu erweitern), die das tut, was Sie wollen (zB zum Beispiel ein zusätzliches builtin, das den Typ seiner Argumente in einer konstanten Zeichenkette kodiert usw.) , aber das erfordert etwas Arbeit (und ist spezifisch für GCC).

Aber ich verstehe nicht, warum Sie solche barocken Dinge in C machen wollen. Wenn dynamisches Tippen für Sie so wichtig ist, warum benutzen Sie keine dynamisch typisierte Sprache?

    
Basile Starynkevitch 28.10.2011 20:23
quelle