首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >2012年VC++中意外的不确定超载解决方案

2012年VC++中意外的不确定超载解决方案
EN

Stack Overflow用户
提问于 2014-09-02 13:13:39
回答 1查看 251关注 0票数 5

视觉C++,2012年。代码。我认为它应该编译;编译器尊敬地不同意。我已经把我的复制品缩小到:

代码语言:javascript
运行
复制
struct  B { };

void foo(B* b, signed int si) { } // Overload 1
void foo(B const* b, unsigned int ui) { } // Overload 2

int main()
{
    B b;
    unsigned int ui;
    foo(&b, ui);
}

所以我们有两位候选人要解决过载问题。对于第一个重载,第一个参数与第二个参数完全匹配,第二个参数需要一个整体转换(未签名为签名)。对于第二个重载,第二个参数完全匹配,第一个参数需要一个cv调整(因为&b是指向非const的指针)。

现在,这似乎应该是完全毫不含糊的。对于重载1,第一个参数是标准的重载解析部分定义的“精确匹配”,而第二个参数是“转换”。对于重载2,这两个参数都是“完全匹配的”(限定转换与标识级别相同)。因此(我的推理显然是不完美的),应该选择过载2,不要含糊不清。然而:

代码语言:javascript
运行
复制
a.cpp(12): error C2666: 'foo' : 2 overloads have similar conversions
    a.cpp(6): could be 'void foo(const B *,unsigned int)'
    a.cpp(5): or       'void foo(B *,int)'
    while trying to match the argument list '(B *, unsigned int)'
    note: qualification adjustment (const/volatile) may be causing the ambiguity

GCC似乎对默认方言和C++11 (谢谢,IDEOne!)的代码都很在行。所以我倾向于把这归咎于MSVC中的一个bug,但是(a)你知道他们对那些认为自己的bug是编译器错误的人说了什么,(b)这似乎是一个很明显的错误,在他们的一致性测试中会发出警告。

这是不符合MSVC,还是不符合GCC?(还是两者兼而有之?)我对过载决议的推理是否合理?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-02 13:17:00

MSVC是正确的。

gcc 4.9.0说:

警告: ISO C++说这些都是模棱两可的,尽管第一个最坏的转换比第二个最坏的转换要好:默认情况下启用。

clang 3.4.1同意这两个函数是不明确的。

尽管B* => B*B* => B const*都具有精确的匹配级别,但前者仍然是每个over.ics.range/3更好的转换序列;这是(例如)以确保:

代码语言:javascript
运行
复制
int f(const int *);
int f(int *);
int i;
int j = f(&i); // calls f(int*)

来自over.ics.level/3:

标准转换序列S1是比标准转换序列S2更好的转换序列。 - S1和S2的资格转换不同,分别产生了相似类型的T1和T2 (4.4),而T1类型的cv-资格签名是T2型资格证书签名的一个适当子集。..。

当然,unsigned int => unsigned intunsigned int => signed int更好。因此,在这两个重载中,一个在第一个参数上有一个更好的隐式转换序列,另一个在第二个参数上有一个更好的隐式转换序列。因此,它们不能被区分为每一个过载的匹配。

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

https://stackoverflow.com/questions/25624303

复制
相关文章

相似问题

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