how does the compiler choose automatic type conversion method

若如初见. 提交于 2019-12-11 07:53:25

问题


In this code, two methods were used to allow conversion of Y object into X object. compiling by g++ always choose constructor. if constructor is private like :
private : Y(const X&){std::cout << "Y constructor...\n" ; }
conversion is prevented either by operator or constructor. if constructor is private and explicit
private : explicit Y(const X&){std::cout << "Y constructor...\n" ; }
compiler use operator instead. Is it the usual way to prevent auto conversion by making conversion constructor private and what is the rule that compiler use to make such kind of conversion.

#include <iostream>

class Y ;

class X {
public:
  operator Y()const ;
};

class Y {
public:
  Y(){}
private : 
  explicit Y(const X&){std::cout << "Y constructor...\n" ; }
};

X::operator Y() const { std:: cout << "Operator Y...\n" ;
 return Y ();
}


void func(Y Y_object) {}

int main() {
  X X_object ;
  Y Y_object ;

  func(X_object) ;
  Y_object = X_object ;
}

回答1:


The most usual way to prevent implicit type conversion is not to declare conversion operator at all and make the constructor explicit. However, if you want to keep the conversion operator, you can make explicit too using explicit keyword:

class X {
public:
  explicit operator Y() const;
};



回答2:


Conversion functions and converting-constructors designate conversions from the type for which the conversion function/constructor is made to the type that is taken in the parameter. In other words, you are converting from an X to a Y and not the other way around as you said.

When there is a conversion from X to Y, the compiler considers the best conversion possible through function overload resolution. Since access control is not considered during overload resolution, it is possible for a private conversion to be chosen over one that is public if the private one is a more viable conversion. There can also be an ambiguity between two conversions if they are both equally viable.


Calling the function func(X_object) requires an implicit conversion from X to Y. Considering both X::operator Y() const and the converting constructor explicit Y::Y(const X&), the conversion operator is chosen because the constructor is marked as explicit and therefore only can be called through the direct-initialization syntax or an explicit cast.

func(Y(X_object));
func(static_cast<Y>(X_object));

These both call the explicit converting-constructor because the argument type of the constructor and parameter matches exactly.


The same situation occurs when using copy-assignment to implicitly convert an X to a Y. The implicit conversion operator is a more viable function than the explicit constructor:

Y_object = X_object; // calls X_object.operator Y()

If direct-initialization syntax or an explicit cast is used, the converting-constructor will be the best viable function.


To prevent an implicit conversion from an X to a Y, it is best that you give Y an explicit constructor rather than an explicit conversion operator. In this case there doesn't seem to be a reason to make the constructor private unless you want to prevent the conversion all together, but if you wanted to do that then simply leave the constructor undeclared.



来源:https://stackoverflow.com/questions/26408312/how-does-the-compiler-choose-automatic-type-conversion-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!