3

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

类型匹配不应该已经排除了第二个构造函数,因为它是“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);
}

我可以通过指定一个参考来解决这个问题 'ie. basic_string &myString' 但如果它是 'const basic_string &myString' 则不是。

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

我怀疑这与通过固有的“!= 0”将每个表达式/类型解析为布尔值有关。

好奇的评论都一样:)

4

1 回答 1

5

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

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

因此,考虑“损坏”的重载:

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

第一个参数是 aconst char[5]并且更喜欢(2)(根据上面的描述)。第二个参数是 anEMyEnum和 prefers (1),它是完全匹配的;需要进行转换才能匹配(2)(枚举可以隐式转换为 a 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)

于 2010-05-28T01:38:21.353 回答