Can `&&` inside a higher order function parameter be a forwarding reference?

76 Views Asked by At

The canonical example of a forwarding (or universal reference) goes like so:

template<typename T>
void f(T&& param); 

i.e.

"If a variable or parameter is declared to have type T&& for some deduced type T, that variable or parameter is a universal reference."

But consider a more contrived example:

 #include <iostream>

 class MyClass
 {
     int _val;

   public:
     void set_val(int &&newVal)
     {
         _val = newVal;
         std::cout << "New val = " << _val << std::endl;
     }
 };

 template <class T, class V> void evoke(void (T::*method)(V &&))
 // The && appears inside the context of a function type  ^^^^ argument
 {
     T obj;
     (obj.*method)(2);
 }

 int main()
 {
     evoke(&MyClass::set_val);
 }

In such cases I find it puzzling to follow the aforementioned rule. V is certainly deduced, but not on its own. Even though it's not a forwarding reference in the example above, can such constructs (function or member function pointer parameters) produce a forwarding reference for their arguments? Does the rule still apply in such cases?

1

There are 1 best solutions below

0
463035818_is_not_an_ai On BEST ANSWER

No.

From cppreference (emphasize mine):

Forwarding references are a special kind of references that preserve the value category of a function argument, making it possible to forward it by means of std::forward. Forwarding references are either:

  1. function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template:

[... examples ...]

  1. auto&& except when deduced from a brace-enclosed initializer list:

[... more examples ...]

For what its worth, the relevant section in the standard is [temp.deduct.call]. My standardese is not fluent, but to my understanding the description on cppreference (must be parameter of a function template) is accurate.