2013-02-05 9 views
13

Wenn ich den folgenden Code mit MSVC++ kompilieren, bekomme ich eine Fehlermeldung:Template Funktionstyp Abzug und Operator << C++

struct A 
{ 
    template<typename T> 
    void operator<<(T&& x) 
    { 
    } 

}; 
void f() 
{ 
} 
int main() 
{ 
    A().operator<<(f); // ok 
    A() << f;    // error 

    return 0; 
} 

g ++ und Klirren sowohl diesen Code in Ordnung kompilieren. AFAIK 'ok' und 'Fehler' Linien tun genau das Gleiche, und geben T zu Lücke geschlossen wird (&)(). Oder ist es void() und Rvalue Verweise auf die Funktion sind erlaubt? Wenn ja, welche Bedeutung haben sie? Ist es in Ordnung, Funktionen als Referenz zu übergeben? Ist es MSVC++ Fehler, der es kompiliert 'Fehler' Zeile? BTW, die Fehlerausgabe:

no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) 
could be 'void A::operator <<<void(void)>(T (__cdecl &&))' 
with[ T=void (void) ] 
+1

können Sie die Version Ihres c liefern ++ Compiler? – xis

+0

MSVC++ 2012 mit NOV CTP Update, gcc 4.5.3 und 4.7.2 getestet, clang 3.0 und 3.1 getestet. – dsi

+0

Ich habe kein VC11, daher ist es schwer für mich zu untersuchen, aber es riecht wie ein Bug mit URef kollabiert. Der Compiler interpretiert es fälschlicherweise als RRef, um zu funktionieren, und akzeptiert keinen lvalue in der Eingabe. Es wäre interessant zu überprüfen, ob 'typedef void (* test)(); Test g() {return f; } ... A() << g(); 'würde funktionieren –

Antwort

2

So nennen, meine eigene Frage zu beantworten:

Der angegebene Code ist gültig und während rvalue Verweise auf Funktionen nutzen darf (sie wirken identisch zu lvalue-Referenzen), hier sollte T während der Template-Deduktion ungültig werden (&)().

Ein bug in MSVC verhindert die Kompilierung meines Codes.

UPDATE: Der Fehler in Visual Studio 2013 wurde Compiler feste

4

Warum void operator<<(T&& x)? void operator<<(T& x) dient dem Zweck.

Funktion kann mit x() innen überladene Funktion, wie unten

struct A 
{ 
    template<typename T> 
    void operator<<(T& x) 
    { 
     x(); 
    } 

}; 
void f() 
{ 
} 

int main() 
{ 
    A().operator<<(f); 
    A() << f;    
    return 0; 
} 
+0

Nein, ich verwende rvalue-Referenz, so dass temporäre _function objects_ verschoben, nicht kopiert werden. Für _functions_ jeder Weg wird jedoch das gleiche funktionieren. – dsi