[英]How does the compiler know which function to pick for a polymorphic type?
例如,我以两种不同的方式重载了operator<<
:
ofstream & operator<<(ofstream & fout, const Thing & t);
ostream & operator<<(ostream & out, const Thing & t);
之所以这样做,是因为我希望文件输出与控制台输出不同。 据我所知, ofstream
是从ostream
派生的,所以当我执行类似的操作时,编译器如何知道如何使用ofstream
来选择重载运算符,而不是仅仅使用ostream
来选择重载运算符?
ofstream fout("file.txt")
fout.open();
Thing t;
fout << t;
因为即使没有使用ofstream
的重载运算符,该代码仍然可以与ostream
一起使用。
通常,其参数与参数最匹配的候选函数就是被调用的函数。
它选择最接近的匹配,ofstream重载更加接近,但是如果没有其他重载,则ostream有效。 如果存在完全匹配的内容,它将进行匹配。
在重载解析开始之前,将通过名称查找和模板参数推导选择的函数组合在一起,以形成一组候选函数(确切的条件取决于进行重载解析的上下文)
重载解析考虑的参数-参数隐式转换序列与复制初始化(用于非引用参数)中使用的隐式转换相对应,不同之处在于当考虑转换为隐式对象参数或赋值运算符的左侧时,不考虑创建临时对象。 每种类型的标准转换序列都被分配以下三个等级之一:
完全匹配:无需转换,左值到右值转换,资格转换,函数指针转换,(自C ++ 17起)类类型到相同类的用户定义转换
促销:积分促销,浮点促销
转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔值转换,用户定义的派生类到其基类的转换
标准转化顺序的排名是它所持有的标准转化的排名中最差的(最多可能有3次转化)
重载分辨率始终优先选择精确匹配(如果有)。 由于没有精确匹配std::ofstream
,请参见本关于重载的更多信息。 std::ostream
也匹配,但优先级较低。 如果消除了所有其他更高优先级的重载,例如消除了std::ofstream
重载,它将被使用。
ofstream
源自ostream
。 所以,
ofstream
对象将在可接受的ofstream
对象的任何地方使用。 除此以外,
可以在可接受ostream
对象的任何地方使用ofstream
对象。
有关参考绑定的 C ++规范N3690:
当引用类型的参数直接绑定(8.5.3)到参数表达式时,隐式转换序列是恒等转换,除非参数表达式的类型是参数类型的派生类,在这种情况下,隐式转换序列是派生到基本的转换(13.3.3.1)。
struct A {}; struct B : public A {} b; int f(A&); int f(B&); int i = f(b); // calls f(B&), an exact match, rather than // f(A&), a conversion
简单来说:
当参数具有类类型且参数表达式具有相同类型时,隐式转换序列为身份转换。
当参数具有类类型并且参数表达式具有派生类类型时, 隐式转换序列是从派生类到基类的派生到基类的转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.