首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >最佳可行转换函数

最佳可行转换函数
EN

Stack Overflow用户
提问于 2019-06-11 14:30:19
回答 1查看 129关注 0票数 2

在下面的程序中,应该选择哪个(如果有的话)转换函数,以及为什么?

代码语言:javascript
代码运行次数:0
运行
复制
int r;
struct B {};
struct D : B {};
struct S {
  D d;
  operator D&(){r=1; return d;} // #1
  operator B&(){r=2; return d;} // #2
};
int main() {
  S s;
  B& b = s;
  return r;
}

gcc和clang都选择了转换函数#2,但是为什么呢?

标准他说

(1)在dcl.init.ref中指定的条件下,引用可以直接绑定到将转换函数应用于初始化表达式的结果。重载解析用于选择要调用的转换函数。假设“对cv1 T的引用”是被初始化的引用的类型,而“cv1”是初始化表达式的类型,对于S是一个类类型,则选择候选函数如下: (1.1) -考虑S及其基类的转换函数。那些不隐藏在S中的非显式转换函数和屈服类型“cv2 T2的lvalue引用”(当初始化lvalue引用或对函数的rvalue引用时)或“cv2 T2”或“对cv2 T2的rvalue引用”(当初始化rvalue引用或对函数的lvalue引用时),其中“cv1 T”是与“cv2 T2”兼容的引用。对于直接初始化,那些未隐藏在S中的显式转换函数和屈服类型“lvalue引用到cv2 T2”(初始化lvalue引用或对函数的rvalue引用时)或“cv2 T2的rvalue引用”(当初始化rvalue引用或对函数的lvalue引用时),其中T2是与T相同的类型,或者可以通过限定转换转换为T类型,也是候选函数。 (2)参数列表有一个参数,即初始值表达式。 注意:这个参数将与转换函数的隐式对象参数进行比较。- end注意事项 

这里我们有两个候选函数#1和#2,它们都是可行的--如果其中一个被删除,程序仍然会编译。这两个转换函数只使用隐式参数,并对其具有相同的cv-和ref-限定。因此,没有一个应该是最可行的,程序也不应该编译。它为什么要编译?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-11 15:03:17

如您所知,过载分解分三个阶段进行:(1)枚举候选函数;(2)确定哪些候选函数是可行的;(3)选择最佳可行函数。

根据Over.Match.最好的/1:

..。一个可行的函数F1被定义为比另一个可行函数F2更好的函数,如果对于所有参数i,ICSi(F1)不是比ICSi(F1)更差的转换序列,那么

  • 对于某些参数j,ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是这样,
  • 上下文是用户定义的转换(参见11.6、16.3.1.5和16.3.1.6)的初始化,从F1的返回类型到目标类型的标准转换序列(即正在初始化的实体的类型)比从F2返回类型到目标类型示例的标准转换序列要好.或者,如果不是那样,
  • ..。进一步的平局规则..。

s到#1或#2的隐式对象参数所需的隐式转换是身份转换,因此ICS1(#1)和ICS2(#1)是不可区分的,第二个要点在这里是相关的。在#1的情况下,需要从转换函数的返回类型(即D& )转换为所需的类型,即B&。对于#2,标准转换序列是身份转换(B&B&),这更好。因此,在这种情况下,选择函数#2比#1更好。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56546047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档