C++ 枚举、具有类似转换的构造函数重载

C++ 枚举、具有类似转换的构造函数重载,c++,visual-c++,enums,constructor-overloading,C++,Visual C++,Enums,Constructor Overloading,为什么VisualC++(2008)在我将枚举指定为第二个参数时会混淆“C2666:2重载具有类似的转换”,而在我定义bool类型时却没有 类型匹配是否应该排除第二个构造函数,因为它是“基本字符串”类型 #include <string> using namespace std; enum EMyEnum { mbOne, mbTwo }; class test { public: #if 1 // 0 = COMPILE_OK, 1 = COMPILE_FAIL tes

为什么VisualC++(2008)在我将枚举指定为第二个参数时会混淆“C2666:2重载具有类似的转换”,而在我定义bool类型时却没有

类型匹配是否应该排除第二个构造函数,因为它是“基本字符串”类型

#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);
}
#包括
使用名称空间std;
enum EMyEnum{mbOne,mbTwo};
课堂测试{
公众:
#如果1//0=编译\u正常,则1=编译\u失败
测试(基本字符串myString,EMyEnum myBool2){}
测试(bool-myBool,bool-myBool2){}
#否则
测试(基本字符串myString,bool myBool2){}
测试(bool-myBool,bool-myBool2){}
#恩迪夫
};
void testme(){
测试(“测试”,mbOne);
}
我可以通过指定一个引用“ie.basic\u string&myString”来解决这个问题,但如果它是“const basic\u string&myString”,则不能

也可以通过“test((basic_string)“test”,mbOne);“显式调用

我怀疑这与每个表达式/类型都通过一个固有的“=0’


好奇的评论都一样:)

产生歧义的原因是一个候选函数比另一个候选函数更好,只有当它的参数没有一个比另一个的参数更匹配时

问题在于字符串文本(其类型为
const char[5]
)可以转换为
std::string
(通过转换构造函数)和
bool
(因为数组可以衰减为指针,并且任何指针都可以隐式转换为
bool
)。首选转换为
bool
,因为它是标准转换,标准转换优于用户定义的转换

因此,考虑“破碎”重载:

test(basic_string<char> myString, EMyEnum myBool2) { }  // (1)
test(bool myBool, bool myBool2) { }                     // (2)
第一个参数仍然首选
(4)
,但现在第二个参数可以同时匹配
(3)
(4)
。因此,编译器可以选择
(4)
,并且没有歧义

如果消除了第一个参数所需的转换,则不会出现歧义,例如

test(basic_string<char>("test"), mbOne);
测试(基本字符串(“测试”),mbOne);

因为这两个参数将完全匹配
(1)

的附录B中可以找到过载解决方案的最佳描述之一。本书的其余部分也很好,但该附录提供了一个非常简洁、易于参考的重载解决规则列表。
test(basic_string<char>("test"), mbOne);