【发布时间】:2016-12-09 10:24:27
【问题描述】:
我被 MSVC 意外匹配的 C++ 函数所困扰。我可以将其简化为以下测试用例:
#include <iostream>
enum Code { aaa, bbb };
struct MyVal {
Code c;
MyVal(Code c): c(c) { }
};
void test(int i, MyVal val) {
std::cout << "case " << i << ": value " << val.c << std::endl;
}
void test(int i, double* f) {
std::cout << "case " << i << ": WRONG" << std::endl;
}
const Code v1 = aaa;
Code v2 = aaa;
const Code v3 = bbb;
int main() {
const Code w1 = aaa;
Code w2 = aaa;
const Code w3 = bbb;
test(1, v1); // unexpected MSVC WRONG
test(2, v2);
test(3, v3);
test(4, aaa);
test(5, w1); // unexpected MSVC WRONG
test(6, w2);
test(7, w3);
return 0;
}
我预计所有 7 次 test 调用都将匹配第一个重载,并且 GCC (live example) 和 Clang (live example) 与预期匹配:
case 1: value 0
case 2: value 0
case 3: value 1
case 4: value 0
case 5: value 0
case 6: value 0
case 7: value 1
但是 MSVC (live example) 将案例 1 和 5 与“错误”重载相匹配(我在 MSVC 2013 和 2015 中发现了这种行为):
case 1: WRONG
case 2: value 0
case 3: value 1
case 4: value 0
case 5: WRONG
case 6: value 0
case 7: value 1
对于(意外)值为 0 的 const enum 变量,MSVC 似乎更喜欢转换为指针。我本来预计这种行为会出现在文字 0 中,但不会出现在 enum 变量中。
我的问题:MSVC 行为是否符合标准? (也许对于旧版本的 C++?)如果不是,这是一个已知的扩展或错误吗?
【问题讨论】:
-
如何编辑您的问题并包含代码输出以保持完整性?
-
v1明显是Code类型,是msvc 的bug。 -
@Jarod42:问题是空指针常量匹配
double*是否比匹配用户定义的转换更好。test不需要Code所以我认为它不是那么明确。 -
GCC 和 Clang 什么?在什么标准模式下?
-
@RawN:GCC 和 Clang 在所有情况下都更喜欢转换为
MyVal。在枚举值 0 为const(derp) 的情况下,MSVS 更倾向于将枚举值 0 视为空指针常量
标签: c++ visual-c++