3

2番目のパラメーターとして列挙型を指定した場合にVisualC++(2008)が混乱するのはなぜですか?bool型を定義した場合はそうではありませんか?

2番目のコンストラクターは'basic_string'型であるため、型の一致によって2番目のコンストラクターが除外されるべきではありませんか?

#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&myString'ですが、' const basic_string&myString'の場合はそうではありません。

また、「test((basic_string) "test"、mbOne);」を介して明示的に呼び出します。また動作します。

これは、すべての式/タイプが固有の「!=0」を介してブール値に解決されることに関係していると思われます。

すべて同じコメントに興味があります:)

4

1 に答える 1

5

あいまいさの理由は、ある候補関数が別の候補関数よりも優れているのは、そのパラメーターのいずれもが他の候補関数のパラメーターよりも悪い場合に限られるためです。

問題は、型が の文字列リテラルが(変換コンストラクターを介して) と(配列はポインターに崩壊する可能性があり、任意のポインターが暗黙的に に変換できるため) のconst char[5]両方に変換できることです。への変換が推奨されるのは、これが標準の変換であり、標準の変換がユーザー定義の変換よりも優先されるためです。std::stringboolboolbool

したがって、「壊れた」オーバーロードを検討してください。

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

最初の引数はconst char[5]andです(2)(上記の説明に従って)。2 番目の引数はEMyEnumand prefers(1)で、完全一致です。一致させるには変換が必要です(2)(列挙は暗黙的に に変換できますbool)。

次に、2 番目のケースを考えてみましょう。

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

最初の引数は引き続き を優先しますが、2 番目の引数は両方と同等に(4)一致するようになりました。したがって、コンパイラは選択でき、あいまいさはありません。(3)(4)(4)

最初の引数に必要な変換を省略しても、あいまいさはありません。たとえば、

test(basic_string<char>("test"), mbOne);

両方の引数が(1)正確に一致するためです。

于 2010-05-28T01:38:21.353 に答える