2017-09-30 3 views
1

Ich habe eine Reihe von Funktionen, wo ich Template-Spezialisierung verwenden, um Transformationen auf bestimmte Werte durchzuführen. Bei vielen Typen möchte ich die Werte jedoch unverändert weitergeben.Perfekte Weiterleitung von Rückgabewerten, undefiniertes Verhalten?

template< typename arg > 
arg&& convert(arg&& x) 
{ 
    return std::forward<arg>(x); 
} 

Dies scheint groß, aber nach der Antwort here es Gefahr läuft, verlässt eine baumelnde Referenz in einer Aussage wie:

Um einen Wert unverändert Ich habe so etwas wie die folgende Funktion als Standard übergeben:

Wenn ich diese Inline nur in Funktionsargumenten verwende, wird dieses Risiko vermieden?

Zum Beispiel habe ich in undefiniertes Verhalten führen, wenn ich etwas tun wie ...

void foo(int&& x) 
{ 
    // Do something with x... 
} 

foo(convert(5)); 
+0

Einige Kontexte ... wie warum können Sie nicht einfach '5' übergeben oder' std :: move() 'verwenden – StoryTeller

+0

Angenommen, ich wollte einen Wrapper für Funktionen schreiben, die den meisten Typen nichts anhaben, aber zu einem hinzufügen alle Integer aus irgendeinem Grund (das ist nicht mein Anwendungsfall, aber sagen wir mal), dann könnte ich convert für alle Argumente verwenden, unabhängig vom Typ (z. B. in einer Variadic-Funktion), und schreibe eine ganzzahlige Spezialisierung für die konvertiere (x) Vorlage, die zu jeder Ganzzahl eins addiert. – Matt

+0

Ihr Weiterleitungscode ist falsch, es sollte 'std :: forward (x);' sein. – VTT

Antwort

3

Zum Beispiel habe ich in undefiniertes Verhalten führen, wenn ich etwas tun wie ...

Nein, der Regel im Bereich von [class.temporary], Hervorhebung von mir ist:

ein temporäres Objekt zu einem referen gebunden ce Parameter in einem Funktionsaufruf bleibt bestehen, bis die Vervollständigung der Voll-Ausdruck enthält den Anruf.

Unser temporär (5) mit einem Bezugsparameter in einem Funktionsaufruf gebunden ist (auf arg&& in convert()), so bleibt es bis zum Ende des Voll Ausdrucks (das die gesamten foo(convert(5)) ist). Also das ist in Ordnung, solange Sie nicht einen Verweis auf x escape foo() lassen.

Verwandte Themen