2016-04-01 24 views
5

Der folgende Code kompiliert, aber liefert undefinierte Ausgabe in VC++ 2015 (Release) und einen Laufzeitfehler mit other compilers.Zuweisen von std :: function <int(int)> zu std :: function <const int & (const int & x)>

#include <functional> 
#include <iostream> 
int main() 
{ 
    std::function<int(int)> f = [](int x) { return x; }; 
    std::function<const int&(const int& x)> g = f; 
    std::cout << g(42) << std::endl; 
} 

Warum ist die Zuweisung g = f; zulässig?

+0

kompiliert und führt perfekt mit Apfel klingeln –

+1

Sehr relevant/möglich dupe: http://stackoverflow.com/q/32871606/2069064 – Barry

Antwort

5

Betrachten Sie den entsprechenden Code neu geschrieben lambdas oder std::function zu vermeiden:

int f(int x) { return x; } 
int const& g(int const& x) { return f(x); } 

Code Dies ist vollkommen wohlgeformt ist, kehrt das dennoch eine baumelnde Verweis auf eine temporäre und somit wird nicht definiertes Verhalten am Ende verursacht. Der ursprüngliche Code ist aus dem gleichen Grund gültig: Sie können ein Objekt implizit in eine Referenz desselben Typs konvertieren. Unglücklicherweise in diesem Fall.

+0

Vielen Dank. Ihr Beispiel mindestens [erzeugt eine Warnung] (http://codepad.org/o6ejBjn6). Das Beispiel mit 'std :: function' nicht. –

4

Ein rvalue kann an eine const& gebunden werden. A const& kann in einen rvalue konvertiert werden.

dieses Unter:

int f(int x){return x;} 
int const& g(int const& x){ return f(x); } 

Auch der Aufruf von g legal ist, gibt es keine Fehler, aber das Ergebnis g(42) Lesen ist UB - die Referenz baumelt.

Ein guter Compiler wird die Referenz gebunden an temporäre zurückgegeben und warnen sehen.

function prüft einfach, ob die Typen zwischen konvertiert werden können; es gibt keine Lebensdaueranalyse. Möglicherweise sollte es, wie wir diesen Fehler statisch erkennen können.

Verwandte Themen