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)?
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
Das ist völlig in Ordnung IMO –
Ich fühle mich geehrt, dass Leute mit sechsstelligem Ruf meine Frage beantworten! – Bernard