gct
gct

Reputation: 14573

Will C++ always prefer an rvalue reference conversion operator over const lvalue reference when possible?

When writing conversion operators, if I provide both a conversion to const T& and T&&, will C++ always prefer the rvalue operator when possible? This seems to be true in this small test:

#include <algorithm>
#include <stdio.h>

struct holds {
  operator       int&&()      { printf("moving!\n");  return std::move(i); }
  operator const int&() const { printf("copying!\n"); return i;            }

private:
  int i = 0;
};


int main() {
  holds h;
  int val = h;
}

prints:

 ╰─▸ ./test
moving!

But perhaps someone that speaks spec-ese better than I can verify?

Upvotes: 7

Views: 680

Answers (2)

bolov
bolov

Reputation: 75707

So I don't have the energy and time to bury myself in the standard for this one. I am sure someone will.

However I want to point out your assumption is wrong. And you are missing a crucial information: one operator is const, one is not and it turns out this is the deciding factor in your case not && vs const &. Let's see:

Both methods mutable, mutable object:

operator       int&&();
operator const int&() ;
holds h;
int val = h; // compile error

Gives the error:

conversion from 'holds' to 'int' is ambiguous

So you see both conversion operators are equal and none is preferred so there is an ambiguity.

Both methods mutable, const object:

operator       int&&();
operator const int&() ;
const holds h;
int val = h;   // error no viable method

Well, this is an easy and non-interesting one: no mutable method can be called on a const object

&& mutable, const& const, object mutable

operator       int&&();
operator const int&() const;
holds h;
int val = h; // calls holds::operator int&&()

Now the mutable method is preferred because the object is mutable

&& mutable, const& const, object const

operator       int&&();
operator const int&() const;
const holds h;
int val = h;   // calls  holds::operator int const&() const

Now the const method is the only choice as a mutable method cannot be called on a const object.

Upvotes: 2

T.C.
T.C.

Reputation: 137315

There's no such preference.

Your example is actually showing preference for a non-const member function over a const one when called on a non-const object.

Upvotes: 8

Related Questions