Dav*_*ley 3 c++ enums constructor-overloading visual-c++
当我将enum指定为第二个参数时,为什么VisualC++(2008)会混淆"C2666:2重载具有类似的转换",但是当我定义bool类型时却没有?
不应该键入匹配已排除第二个构造函数,因为它是'basic_string'类型?
#include <string>
using namespace std;
enum EMyEnum { mbOne, mbTwo };
class test {
public:
#if 1 // 0 = COMPILE_OK, 1 = COMPILE_FAIL
test(basic_string<char> myString, EMyEnum myBool2) { }
test(bool myBool, bool myBool2) { }
#else
test(basic_string<char> myString, bool myBool2) { }
test(bool myBool, bool myBool2) { }
#endif
};
void testme() {
test("test", mbOne);
}
Run Code Online (Sandbox Code Playgroud)
我可以通过指定引用来解决这个问题.basic_string&myString'但不是'const basic_string&myString'.
也通过"test((basic_string)"test",mbOne"显式调用;" 也有效.
我怀疑这与通过固有的'!= 0'解析为bool的每个表达式/类型有关.
好奇的评论都一样:)
模糊性的原因是,只有当一个候选函数的参数都不比另一个参数更差时,它才优于另一个候选函数.
问题是字符串文字,其类型const char[5]
可以转换为std::string
(通过转换构造函数)和a bool
(因为数组可以衰减为指针,并且任何指针都可以隐式转换为bool
).转换bool
为首选是因为它是标准转化,标准转化优先于用户定义的转化.
所以,考虑"破坏"的重载:
test(basic_string<char> myString, EMyEnum myBool2) { } // (1)
test(bool myBool, bool myBool2) { } // (2)
Run Code Online (Sandbox Code Playgroud)
第一个参数是a const char[5]
并且更喜欢(2)
(根据上面的描述).第二个参数是a EMyEnum
并且更喜欢(1)
,这是完全匹配; 需要进行转换才能匹配(2)
(枚举可以隐式转换为a bool
).
现在考虑第二种情况:
test(basic_string<char> myString, bool myBool2) { } // (3)
test(bool myBool, bool myBool2) { } // (4)
Run Code Online (Sandbox Code Playgroud)
第一个参数还是比较喜欢(4)
,但是现在的第二个参数可以同时匹配(3)
和(4)
平等.因此,编译器可以选择(4)
并且没有歧义.
如果你消除了第一个参数所需的转换,就没有歧义,例如,
test(basic_string<char>("test"), mbOne);
Run Code Online (Sandbox Code Playgroud)
因为两个参数都(1)
完全匹配.