bigdata2
bigdata2

Reputation: 1041

Why is const rvalue reference implicitly converted into const reference?

#include <iostream>
using namespace std;

class foo {
public:
    foo() {}
    foo(const foo& other) {cout << "foo's copy constructor " << endl;}
    foo(foo&& other) {cout << "foo's move constructor " << endl;}
    foo(const foo&& other) {cout << "foo's move constructor with const ref ref" << endl;}
};

class bar {
public:
    bar(const foo& f) : f_(move(f)) {}
    foo f_;
};

int main()
{
    foo f;
    bar b(f);
}

In the above code, in absence of the move constructor -- foo(const foo&& other), the rvalue reference move(f) is implicitly converted into a const reference and thus foo's copy constructor is called.

My question is why a const rvalue reference implicitly converted into a const reference instead of a compiler error? Specifically, if I comment out the last move constructor, then foo's copy constructor is called.

Upvotes: 3

Views: 2155

Answers (1)

M.M
M.M

Reputation: 141544

Some simpler code with the same reference binding:

int main()
{
    const foo f;
    const foo&  g = std::move(f);
    const foo&& h = std::move(f);
}

The expression std::move(f) is best described as an xvalue of type const foo.

So we have a reference being initialized by an xvalue of type const foo.

Both of g and h are legal and the reference binds directly. const foo&& can only bind to an rvalue, but const foo& can bind to both lvalues and rvalues. (An xvalue is an rvalue).

There is no implicit conversion as suggested in the title, the reference binds directly to the object designated by the initializer.


In the posted code there is overload resolution between two constructors with the same binding as g and h in my example. Overload resolution selects parameter type const foo&& as a better match than const foo& to an argument of type const foo and category "xvalue", since there is a ranking rule that rvalue arguments prefer rvalue references if all else is equal.

But if you remove either of those two constructors then the other one will be selected.

Upvotes: 2

Related Questions