繁体   English   中英

编译器如何知道为多态类型选择哪个函数?

[英]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有效。 如果存在完全匹配的内容,它将进行匹配。

在重载解析开始之前,将通过名称查找和模板参数推导选择的函数组合在一起,以形成一组候选函数(确切的条件取决于进行重载解析的上下文)

重载解析考虑的参数-参数隐式转换序列与复制初始化(用于非引用参数)中使用的隐式转换相对应,不同之处在于当考虑转换为隐式对象参数或赋值运算符的左侧时,不考虑创建临时对象。 每种类型的标准转换序列都被分配以下三个等级之一:

  1. 完全匹配:无需转换,左值到右值转换,资格转换,函数指针转换,(自C ++ 17起)类类型到相同类的用户定义转换

  2. 促销:积分促销,浮点促销

  3. 转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔值转换,用户定义的派生类到其基类的转换

标准转化顺序的排名是它所持有的标准转化的排名中最差的(最多可能有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.

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