简体   繁体   中英

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM