枚举,构造函数重载具有类似的转换

时间:2010-05-28 01:27:07

标签: c++ visual-c++ enums constructor-overloading

当我将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);
}

我可以通过指定引用来解决这个问题。 basic_string&amp; myString'但不是'const basic_string&amp; myString'。

还通过“test((basic_string)”test“,mbOne”显式调用;“也有效。

我怀疑这与通过固有的'!= 0'解析为bool的每个表达式/类型有关。

对所有评论都很好奇:)

1 个答案:

答案 0 :(得分:5)

模糊性的原因是,只有当一个候选函数的参数都不比另一个参数的参数更差时,它才优于另一个候选函数。

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

所以,考虑一下“破损”的重载:

test(basic_string<char> myString, EMyEnum myBool2) { }  // (1)
test(bool myBool, bool myBool2) { }                     // (2)

第一个参数是const char[5]并且更喜欢(2)(根据上面的描述)。第二个参数是EMyEnum并且更喜欢(1),这是完全匹配;需要进行转换以匹配(2)(枚举可以隐式转换为bool)。

现在考虑第二种情况:

test(basic_string<char> myString, bool myBool2) { }    // (3)
test(bool myBool, bool myBool2) { }                    // (4)

第一个参数仍然更喜欢(4),但现在第二个参数可以同等地匹配(3)(4)。因此,编译器可以选择(4)并且没有歧义。

如果你消除了第一个参数所需的转换,例如,

,就没有歧义
test(basic_string<char>("test"), mbOne);

因为两个参数都与(1)完全匹配。

相关问题