c++ - 如何比较两个标准转换序列使用包含转换的等级
问题描述
#include <iostream>
void g(int*); //#1
void g(int (&arr)[2]); //#2
void f(int*); //#3
void f(int const*); //#4
int main(){
int arr[2] ={0};
f(arr); // choose #3
g(arr); //ambiguous
}
考虑上面的代码,#3被选择为f(ptr)
,但是,g(arr)
给出了一个ambiguous
诊断。
选择最佳函数的规则定义为:
标准转换序列 S1 是比标准转换序列 S2 更好的转换序列,如果
- S1 是 S2 的适当子序列(比较 [over.ics.scs] 定义的规范形式的转换序列,不包括任何 Lvalue 转换;恒等转换序列被认为是任何非恒等转换序列的子序列)或,如果不是这样
所以看看over.ics.scs#3
这些用于对标准转换序列进行排名。转换序列的排名是通过考虑序列中每个转换的排名和任何参考结合的排名来确定的。
根据我对上述规则的理解,我可以理解为什么#3
是 的最佳重载f(ptr)
,即:
给定 S1 为 (arr => int*):
Array-to-pointer conversion -> (identity conversion)
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
int[2] => int* int* => int*
而给定 S2 为 (ptr => int const*)
Array-to-pointer conversion -> Qualification conversions -> identity conversion
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
int[2] => int* int* => int const* int const* => int const*
由于 identity conversion
是 的适当子序列Qualification conversions
,因此 S1 优于 S2。因此,#3是通过重载决议选择的f(ptr)
。
当我使用类似的过程来确定哪个最适合g(arr)
时,我遇到了一个问题。
同样,给定 S1 为 (arr => int*)
Array-to-pointer conversion -> identity conversion
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
int[2] => int* int* => int*
而给定 S2 as(arr => int (&arr)[2])
当引用类型的参数直接绑定到参数表达式时,隐式转换序列是恒等转换,除非参数表达式的类型是参数类型的派生类,在这种情况下,隐式转换序列是派生的-基数转换
identity conversion
^^^^^^^^^^^^^^^^^^^
bind to reference
在这里,identity conversion
of是ofS2
的正确子序列,因此它应该比 更好,为什么编译器抱怨是一个模棱两可的调用?Array-to-pointer conversion
S1
S1
g(arr)
我对如何对标准转换序列进行排名有任何误读吗?如何比较两个标准 ICS(包含转换的排名)?
解决方案
关键点在这里:
S1 是 S2 的适当子序列(比较 [over.ics.scs] 定义的规范形式的转换序列,不包括任何 Lvalue Transformation;恒等转换序列被认为是任何非恒等转换序列的子序列)或,如果不是这样
这意味着,对于函数调用g(arr)
,所有数组到指针的转换都不会用于确定排名。换句话说,从 typeint[2]
到 type int*
,只有一个用于确定排名的身份转换。因此,S1 ofvoid g(int*);
和 S2 ofvoid g(int (&arr)[2]);
是无法区分的 ICS,因此编译器给出了一个模棱两可的错误。
作为对比,用于比较排名的 void f(int*);
和的转换分别是和。void f(int const*);
identity conversion
qualification conversion
根据规则:
恒等转换序列被认为是任何非恒等转换序列的子序列
因此,Qualification conversion
被认为比 的排名更差identity conversion
。所以,void f(int*)
赢得了比赛。
推荐阅读
- java - 如何返回选择下拉列表的所有选项?
- javascript - NodeJS - 需要模块没有同步工作
- git - 詹金斯管道中的 docker.withDockerRegistry() 问题
- quire-api - Quire API 似乎缺乏将任务添加到板和板列的功能
- javascript - 我得到了这个错误>>渲染没有返回任何内容。这通常意味着缺少 return 语句。或者,不渲染任何内容,返回 null
- javascript - 使用 Axios 或任何其他方法的多个 URL http post 请求
- python - 什么是“未实现错误”
- javascript - 如何在 Vue.js 的下拉列表中设置默认值
- php - 如何使用 php 创建 GuzzleHttp api 得到 404 错误?
- java - 无法从静态上下文错误中引用