2013-07-25 8 views
12

Ich habe dieses Beispiel-Programm:Pass Vorlage args von const & oder &&

#include <iostream> 

template<typename Message, typename Decoration, typename PrintImpl> 
void print_surrounded(Message&& msg, const Decoration& decoration, const PrintImpl& print_impl) 
{ 
    print_impl(decoration); // should forward be used? 
    print_impl(" "); 
    print_impl(std::forward<Message>(msg)); 
    print_impl(" "); 
    print_impl(decoration); 
} 

template<typename Message, typename PrintImpl> 
void pretty_print(Message&& msg, const PrintImpl& print_impl) 
{ 
    print_surrounded(std::forward<Message>(msg), "***", print_impl); 
} 

int main() 
{ 
    pretty_print("So pretty!", [](const char* msg) { 
     std::cout << msg; 
    }); 
} 

I also posted it on Coliru.

Wie Sie ich verschiedene Möglichkeiten sehen die Argumente zu übergeben:

  • Nachricht übergeben wird als universelle Referenz, da sie eventuell an die PrintImpl-Funktion weitergeleitet werden muss.
  • Dekoration als const ref übergibt hier, weil ihr Wert zweimal verwendet wird, und ich bin nicht sicher, würde vorwärts zweimal sicher sein, wenn mit. (Es könnte durch den ersten Vorwärts weggezogen werden?)
  • PrintImpl als const Referenz übergeben, weil ich sehe keinen Grund, nach vorne zu verwenden. Ich bin mir jedoch nicht sicher, ob das klug ist. (Sollte ich vorbei &&? Wenn ja, sollte ich std::forward auch benutzen?)

Mache ich die richtigen Entscheidungen?

+0

ist nicht genau das, was ich habe CPS verstanden. http://en.wikipedia.org/wiki/Continuction-passing_style Ich nehme an, dass Sie in der Zeile des Kommentars fragen, ob Sie 'forward' mit' print_impl' verwenden sollen, nicht 'decoration', oder? – sehe

+0

@sehe Okay, ich habe die CPS Teile entfernt. – StackedCrooked

+0

Nur um klarzustellen: ist "Capture" der richtige Begriff hier? Ich dachte "Capture" ist reserviert für die Erfassung von Variablen durch Closure-Objekte (generiert von Lambda-Ausdrücken). Ist "pass" (eines Arguments) nicht der richtige Begriff? – Walter

Antwort

4

mache ich die richtigen Entscheidungen zu treffen?

Ja (meistens).

Dekoration als const ref hier erfasst, weil sein Wert zweimal verwendet wird, und ich bin nicht sicher, würde vorwärts zweimal sicher sein, wenn mit. (Man könnte von dem ersten Vorwärts weggezogen?)

nicht std::forward Verwenden Sie, wenn Sie es mehrmals tun würde, genau aus dem Grund, Sie legte aus.

PrintImpl wird als const-Referenz erfasst, da ich keinen Grund sehe, vorwärts zu verwenden.

Was möchten Sie vielleicht ist PrintImpl&& tun zu nehmen und verwenden Sie nicht std::forward (sie als lvalues ​​halten), so dass Funktionsobjekte ohne constoperator(), Qualifizierte weitergegeben werden. Diese

+1

Und wenn Sie extrem dumm sind, können Sie 'std :: Vorwärts (print_impl)()' im letzten Aufruf 'in Ihrer Funktion print_impl', falls Ihr' PrintImpl' hat ein '&&' 'qualifizierte Betreiber() '. (Anmerkung: niemand hat einen '&&' qualifizierten 'operator()') – Yakk