2017-05-03 1 views
5

Ich möchte eine Funktion foo schreiben, die operator() seiner Parameter nennen sollte, wie in der unten stehenden (gebrochen) Code dargestellt:Weiterleiten der Const-ness eines Template-Parameters, sollte ich eine Weiterleitungsreferenz verwenden?

template <typename T> void foo(const T& x){ 
    x(); 
} 

struct MyFunctor{ 
    int data; 
    void operator()(){ 
     /* stuff that might modify the data */ 
    } 
}; 

int main() 
{ 
    foo(MyFunctor{}); 
} 

Offensichtlich ist der Code nicht funktioniert, weil operator() nicht ist const, aber foo() erfordert seinen Parameter const.

Als Template-Funktion, foo() sollte mit beiden const und nicht const functors arbeiten, und nicht über die const -ness ihr Argument wählerisch sein.

Wenn ich foo() ändern, indem die const auf die folgende Entfernung:

template <typename T> void foo(T& x) { /* ... */ } 

... es wird auch nicht funktionieren, weil Sie keine rvalue Verweis auf eine nicht const lvalue Referenz umwandeln kann, so foo(MyFunctor{}) kann nicht aufgerufen werden.

Ändern foo() an eine Weiterleitungsreferenz löst alle Probleme:

template <typename T> void foo(T&& x) { /* ... */ } 

Aber das ist die „richtige“ Art und Weise? Sollten keine Weiterleitungsreferenzen nur mit std::forward() verwendet werden (d. H. Der Parameter sollte nicht berührt werden, abgesehen von der Weiterleitung an eine andere Funktion)?

+2

Sie möchten vielleicht lesen [Universalreferenzen in C++ 11-Scott Meyers] (https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers). Es enthält einige eingehende Erklärungen zum Gebrauch von 'T && x'. – VTT

+0

Das ist völlig in Ordnung IMO –

+0

Ich fühle mich geehrt, dass Leute mit sechsstelligem Ruf meine Frage beantworten! – Bernard

Antwort

3

Ja, eine Weiterleitung Referenz ist der richtige Weg, und wenn es Sie beruhigt, können Sie sicher den Parameter weiter:

template <typename T> void foo(T&& x){ 
    std::forward<T>(x)(); 
} 

Jetzt funktioniert es auch mit ref qualifizierten Call-Betreiber.

+1

Ref-qualifizierte Call-Betreiber sind etwas Neues, das Sie mir heute beigebracht haben. – Bernard

0

Ja, dies ist der gesamte Zweck einer Weiterleitungsreferenz.

der Parameter nicht auseinander es auf eine andere Funktion berührt werden sollten

das ist genau das, was Sie tun weiterleitet.

Verwandte Themen