In Scott Meyer's book Effective Modern C++ on page 167 (of the print version), he gives the following example:
auto timeFuncInvocation = [](auto&& func, auto&&... params) {
// start timer;
std::forward<decltype(func)>(func)(
std::forward<decltype(params)>(params)...
);
// stop timer and record elapsed time;
};
I completely understand the perfect forwarding of params
, but it is unclear to me when perfect forwarding of func
would ever be relevant. In other words, what are the advantages of the above over the following:
auto timeFuncInvocation = [](auto&& func, auto&&... params) {
// start timer;
func(
std::forward<decltype(params)>(params)...
);
// stop timer and record elapsed time;
};
Perfect forwarding reduces excessive copying and simplifies code by reducing the need to write overloads to handle lvalues and rvalues separately. Note: The function the arguments are forwarded to can be a normal function, another template function, or a constructor.
std::forward helps to implement perfect forwarding. This mechanism implies that objects passed to the function as lvalue expressions should be copied, and objects passed to the function as rvalue expressions should be moved. If you assign an rvalue reference to some ref variable, then ref is a named entity.
Perfect forwarding makes it possible to write function templates that take arbitrary arguments and forward them to other functions such that the target functions receive exactly the same arguments as were passed to the forwarding functions.
I understand that a forwarding reference is "an rvalue reference to a cv-unqualified template parameter", such as in. template <class T> void foo(T&& ); which means the above function can take both l-value and r-value reference.
For the same purpose as for arguments: so when Func::operator()
is a ref-qualified:
struct Functor
{
void operator ()() const & { std::cout << "lvalue functor\n"; }
void operator ()() const && { std::cout << "rvalue functor\n"; }
};
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With