Visual C++ 2012. コード。コンパイルする必要があると思います。コンパイラは丁重に同意しません。再現を次のように絞り込みました。
struct B { };
void foo(B* b, signed int si) { } // Overload 1
void foo(B const* b, unsigned int ui) { } // Overload 2
int main()
{
B b;
unsigned int ui;
foo(&b, ui);
}
したがって、過負荷解決の候補が 2 つあります。最初のオーバーロードの場合、最初の引数は正確に一致し、2 番目の引数は整数変換 (符号なしから符号付き) を必要とします。2 番目のオーバーロードの場合、2 番目の引数は正確に一致し、最初の引数には cv 調整が必要です (&b
は非 const へのポインターであるため)。
さて、これは完全に明白であるように思われます。オーバーロード 1 の場合、最初の引数はオーバーロードの解決に関する標準のセクションで定義されている「完全一致」ですが、2 番目の引数は「変換」です。オーバーロード 2 の場合、両方の引数が「完全一致」です (修飾変換は ID と同じランクになります)。したがって (私の明らかに不完全な推論が続く)、過負荷 2 を曖昧さなく選択する必要があります。それでも:
a.cpp(12): error C2666: 'foo' : 2 overloads have similar conversions
a.cpp(6): could be 'void foo(const B *,unsigned int)'
a.cpp(5): or 'void foo(B *,int)'
while trying to match the argument list '(B *, unsigned int)'
note: qualification adjustment (const/volatile) may be causing the ambiguity
GCC は、デフォルトの方言と C++11 (ありがとう、IDEOne!) の両方で、コードに問題ないようです。したがって、私はこれを MSVC のバグに結び付ける傾向がありますが、(a) 自分のバグをコンパイラのバグだと考えている人々について彼らが何を言っているのか知っています。(b) これはかなり明らかなバグのようです。 、適合性テスト中に危険信号を送信したであろう種類。
これは非準拠の MSVC ですか、それとも非準拠の GCC ですか? (または両方?) 過負荷の解決に関する私の推論は適切ですか?