C++ 编译器如何选择自动类型转换方法

C++ 编译器如何选择自动类型转换方法,c++,constructor,C++,Constructor,在这段代码中,使用了两种方法将Y对象转换为X对象。用g++编译总是选择构造函数。如果构造函数是私有的,如: private:Y(const X&){std::cout防止隐式类型转换的最常用方法是根本不声明转换运算符并使构造函数显式化。但是,如果要保留转换运算符,也可以使用explicit关键字显式化: class X { public: explicit operator Y() const; }; 转换函数和转换构造函数指定从转换函数/构造函数所针对的类型到参数中采用的类型的转换。换句

在这段代码中,使用了两种方法将Y对象转换为X对象。用g++编译总是选择构造函数。如果构造函数是私有的,如:

private:Y(const X&){std::cout防止隐式类型转换的最常用方法是根本不声明转换运算符并使构造函数显式化。但是,如果要保留转换运算符,也可以使用
explicit
关键字显式化:

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

转换函数和转换构造函数指定从转换函数/构造函数所针对的类型到参数中采用的类型的转换。换句话说,您正在从
X
转换为
Y
,而不是像您所说的那样

当存在从
X
Y
的转换时,编译器会考虑通过函数重载解析可能实现的最佳转换。由于在重载解析期间不考虑访问控制,如果私有转换是更可行的转换,则可以选择私有转换而不是公共转换。如果两种转换都是同样可行的,则两种转换之间也可能存在歧义


调用函数
func(X_对象)
需要从
X
Y
的隐式转换。考虑到
X::操作符Y()常量
和转换构造函数
显式Y::Y(常量X&)
,选择转换运算符是因为构造函数标记为显式
,因此只能通过直接初始化语法或显式转换调用

func(Y(X_object));
func(static_cast<Y>(X_object));
如果使用直接初始化语法或显式转换,则转换构造函数将是最可行的函数



为了防止从
X
Y
的隐式转换,最好给
Y
一个显式构造函数,而不是显式转换运算符。在这种情况下,似乎没有理由将构造函数设为私有,除非您想同时阻止转换,但如果您想这样做的话然后就不需要声明构造函数了。

我发现显式运算符是c++11特性,如编译结果所示,我还想知道为什么编译器选择构造函数而不是运算符来进行转换。我不确定这是否是一个标准,例如,如果您将运算符声明为
运算符Y&()const
,只进行一次转换
Y\u object=X\u object
编译器将仅选择运算符并跳过constructor@user3270926是的,我错了。它总是选择最佳匹配的转换。您在这段代码中看到的输出是什么?
运算符Y…
,而输出是
Y constructor
如果Y()不是私有的,也不是显式的。您说过编译器可能会选择最好的转换方法;我认为最好的方法是只提供一种转换方法。还有一件事;我发现,如果运算符像
运算符Y&()那样声明,则将转换构造函数声明为私有不会阻止转换const
。可能编译器首先查找构造函数不是标准做法。@user3270926如上所述,在重载解析过程中不考虑访问控制。无论某些内容是否声明为私有,编译器仍将查找要调用的最佳函数。此外,编译器查找可行函数的顺序也不确定函数。它将函数编译成一组候选函数,并根据特定规则选择最佳函数。没有对其中任何一个进行优先选择。
func(Y(X_object));
func(static_cast<Y>(X_object));
Y_object = X_object; // calls X_object.operator Y()