【发布时间】:2017-07-27 14:02:25
【问题描述】:
(所有测试均在 Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86 上执行)
考虑这个最小的例子:
struct myString
{
operator const char *( ) const { return &dummy; }
char& operator[]( unsigned int ) { return dummy; }
const char& operator[]( unsigned int ) const { return dummy; }
char dummy;
};
int main()
{
myString str;
const char myChar = 'a';
if( str[(int) 0] == myChar ) return 0; //error, multiple valid overloads
}
根据重载解析规则(来自 cppreference)
如果隐式,F1 被确定为比 F2 更好的函数 F1 的所有参数的转换并不比隐式差 F2 的所有参数的转换,以及
1) 至少有一个 F1 的参数,其隐式转换优于 F2 的那个参数对应的隐式转换
2) 或。如果 不是那样,(仅在通过转换进行非类初始化的情况下), 从 F1 的返回类型到 正在初始化的类型优于标准转换序列 来自F2的返回类型
char& operator[]( unsigned int ) 应该更好,根据 1)。
这两个参数中(this = myString)根本不需要转换,operator const char *( ) const 将其转换为 const char*,const char& operator[]( unsigned int ) const 将其转换为 const myString,因此有一个参数没有任何隐式转换,这恰好是最好的转换
但是我的编译器会报以下错误:
1> [///]\sandbox\sandbox\sandbox.cpp(29): error C2666: 'myString::operator []': 3 overloads have similar conversions
1> [///]\sandbox\sandbox\sandbox.cpp(19): note: could be 'const char &myString::operator [](unsigned int) const'
1> [///]\sandbox\sandbox\sandbox.cpp(18): note: or 'char &myString::operator [](unsigned int)'
1> [///]\sandbox\sandbox\sandbox.cpp(29): note: while trying to match the argument list '(myString, int)'
另请注意,使用if( str[0u] == myChar ) return 0; 或删除operator const char *( ) const 可解决错误
为什么这里有错误,我对重载解析规则有什么误解?
编辑:这可能是这个版本中的一个视觉 C++ 错误,对此有任何明确的确认吗?
【问题讨论】:
-
用 gcc/clang here 编译。
-
编译器声称有三个候选重载,但只提到其中两个,这让我有点惊讶。
-
有趣。我有版本 19.10.25019,它对我来说编译得很好。可能只是他们修复的一个错误。
-
它是可视化 C++ 编译器,我也花了一些时间在 clang 上进行了测试,它确实编译得很好
-
@nathanoliver ,这可能是我的版本中的一个错误,我会尝试检查补丁说明(编辑:如果我找到那些)
标签: c++ language-lawyer overload-resolution