2013-03-23 16 views
12

ich den folgenden Code mit GCC, Clang, ICC und VS getestet:Kann eine Rvalue-Referenz an eine Funktion gebunden werden?

void f() {} 

void g(void (&&)()) { } 

int main() { 
    g(f); 
} 

Wie wir sehen können, g nimmt eine rvalue Referenz aber f ist ein L-Wert und im Allgemeinen kann rvalue Referenzen nicht zu lvalues ​​gebunden werden . Das ist genau das, was ICC klagt über:

error: an rvalue reference cannot be bound to an lvalue 

VS gibt auch ein Fehler aber aus einem anderen Grund:

error C2664: 'void h(void (__cdecl &&)(void))' : cannot convert parameter 1 from 'void (__cdecl *)(void)' to 'void (__cdecl &&)(void)' 

Dies legt nahe, mir, dass VS sofort führt eine Funktion zu Zeiger Umwandlung, anstatt direkt die Referenz an f zu binden. Es ist erwähnenswert, dass, wenn ich g(f) durch g(&f) ersetze, die vier Compiler genau diesen gleichen Fehler ergeben.

Schließlich GCC und Clang akzeptieren den Code und ich glaube, dass sie korrekt sind. Meine Überlegung basiert auf 8.5.3/5

A reference „CV1 T1“ zu geben, indem ein Ausdruck des Typs „CV2 T2“ als

initialisiert wird - Wenn die Referenz ein L-Wert Referenz [ist. ..]

- Andernfalls [...] soll die Referenz eine R-Referenz sein.

        - Wenn der Initialisierer Ausdruck ist ein [...] Funktion lvalue [...]

        dann die Bezugnahme auf den Wert des gebundenen Initialisierungsausdruck [...]

Ist meine Interpretation korrekt (dass sind Clang und GCC aus dem genannten Grund konform)?

Antwort

9

Ist meine Interpretation korrekt [...]?

Ja.

Ihre Interpretation stimmt mit dem von Ihnen zitierten Absatz des Standards. Eine weitere Bestätigung von Paragraph kommt 13.3.3.1.4/3 auf Referenzbindung:

Mit Ausnahme eines impliziten Objektparameter, für die 13.3.1 zu sehen, eine Standardkonvertierungssequenz nicht gebildet werden kann, wenn es sich um eine Bindung erfordert Lvalue-Referenz mit Ausnahme eines Verweises auf einen nichtflüchtigen const-Typ auf Ein rvalue oder Binden eines rvalue-Referenzwerts an einen lvalue anders als eine Funktion lvalue. [...]

Ziffer 13.3.3.2/3 enthält eine weitere (indirekt) Bestätigung:

[...] Standardkonvertierungssequenz S1 ist eine bessere Umwandlungsfolge als S2 Standardkonvertierungssequenz, wenn

- [...]

- S1 und S2 sind Referenzbindungen (8.5.3) und ein L-Wert S1 bindet Verweis auf eine Funktion lvalue und S2 bindet rvalue Verweis auf eine Funktion lvalue. [Beispiel:

int f(void(&)()); // #1 
int f(void(&&)()); // #2 
void g(); 
int i1 = f(g); // calls #1 

- Ende Beispiel]

+0

der Tat. Ich habe das vorher getestet und alle vier Compiler sind konform. –

+0

@CassioNeri: OK, danke für das Teilen der Informationen –

Verwandte Themen