OMGtechy - 4 months ago 58

C++ Question

Take the following member function:

`struct T {`

template <typename X> void f(X&& x) { /* ... */ }

};

In this case,

`x`

`&&`

Now take this function:

`struct T {`

template <typename X> void f(X&& x) && { /* ... */ }

};

I would expect that

`this`

`#include <iostream>`

struct T {

template <typename X>

bool operator<(X&& rhs) && {

std::cout << "&&" << std::endl;

return true;

}

};

int main() {

T t;

std::cout << (t < T()) << std::endl;

return 0;

}

But using GCC 4.8.4 and 6.0.1, it does not. Instead, I get the following:

`rvalue.cpp: In function ‘int main()’:`

rvalue.cpp:13:25: error: passing ‘T’ as ‘this’ argument of ‘bool T::operator<(X&&) && [with X = T]’ discards qualifiers [-fpermissive]

std::cout << (t < T()) << std::endl;

It would appear that

`this`

Is this correct or an error? Should

`this`

Answer

The two `&&`

s` here are treated differently:

```
struct T {
template <typename X> void f(X&& x) && { /* ... */ }
};
```

You are correct in that `x`

is a forwarding reference. But the `&&`

on the right is a qualification on the object instance. In this case, `f()`

can only be invoked if the object instance is an rvalue (perhaps adding to the confusion is that the first `&&`

takes `x`

as a forwarding reference but the second `&&`

takes the implicit `this`

argument as an rvalue reference). That is:

```
T().f(4); // ok
T t;
t.f(4); // error
```

This works the same way as `const`

qualification does:

```
struct X { void f(); };
const X cx;
cx.f(); // error
```