vendredi 29 juin 2018

Conversion operator vs deleted constructor

Please see the following code:

struct X;

struct Y {
  Y() {}
  Y(X&) = delete;
};

struct X {
  X() {}
  operator Y() {
    return{};
  }
};

int main() {
  X x;
  static_cast<Y>(x);
}

Here, the Y's constructor taking an X is explicitly deleted, while X has a conversion operator into Y. Among these directly contradicting two, it seems that =delete always win; I tested on some recent versions of GCC, Clang, and VC++.

The question: is it the "right" behavior? I thought there is no particular precedence between conversion constructor and conversion operator, so the code above should produce an overload resolution ambiguity error. But it doesn't. It complains about usage of the deleted function. Is it because of the guaranteed copy elision?

I googled and found Conversion constructor vs. conversion operator: precedence. In that question, the conversion operator has been chosen because it was a better match due to presence of const in the conversion constructor. However, in my case replacing Y(X&) to Y(X const&) changed nothing.


Actually, the situation I want to have is the following:

X x;
Y y1(x);                  // Error
Y y2 = static_cast<Y>(x); // OK

Yes, one may call this silly, but indeed there are built-in types that behave just like that: substitute X <- int&, Y <- int&&. Inability to make a user-defined type that exactly mimics a built-in reference type seems to be a really desperately missing piece in current C++...

Aucun commentaire:

Enregistrer un commentaire