When redirecting a template parameter constant, should I use a forwarding link?

I want to write a function foo , which should call the operator() its parameter, as shown in the (broken) code below:

 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{}); } 

Obviously, the code does not work because operator() not const , but foo() requires that its parameter be const .

As a template function, foo() should work with both const and non- const functors, and not be picky about the const -ness of its argument.

If I modify foo() by removing const as follows:

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

... it will not work either, because you cannot convert the rvalue link to a const lvalue link, so foo(MyFunctor{}) cannot be called.

Changing foo() to the forwarding link fixes all the problems:

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

But is this the "right" way? If forwarding links should not be used only with std::forward() (that is, the parameter should not touch separately from forwarding its other function)?

+5
source share
2 answers

Yes, the forwarding link is the right way, and if it reassures you, you can redirect the parameter:

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

Now it even works with reflex call operators.

+3
source

Yes, this is the whole purpose of the forwarding directory.

the parameter should not be touched separately from forwarding it to another function

This is exactly what you are doing.

0
source

All Articles