この例はVC10とgccでコンパイルされているようです(私のバージョンのgccは非常に古いですが)。
編集:R。MartinhoFernandezはgcc4.7でこれを試しましたが、動作は同じです。
struct Base
{
operator double() const { return 0.0; }
};
struct foo
{
foo(const char* c) {}
};
struct Something : public Base
{
void operator[](const foo& f) {}
};
int main()
{
Something d;
d["32"];
return 0;
}
しかし、clangは文句を言います:
test4.cpp:19:6: error: use of overloaded operator '[]' is ambiguous (with operand types 'Something' and 'const char [3]')
d["32"]
~^~~~~
test4.cpp:13:10: note: candidate function
void operator[](const foo& f) {}
^
test4.cpp:19:6: note: built-in candidate operator[](long, const char *)
d["32"]
^
test4.cpp:19:6: note: built-in candidate operator[](long, const restrict char *)
test4.cpp:19:6: note: built-in candidate operator[](long, const volatile char *)
test4.cpp:19:6: note: built-in candidate operator[](long, const volatile restrict char *)
過負荷の解決では、この式を見て2つの可能な関数を検討しています。
- Something :: operator []の呼び出し(ユーザー定義の変換後)
- const char *の組み込み演算子を呼び出します( "32" [d]と考えてください)(ユーザー定義の変換と標準のdoubleからlongへの変換後)。
私がd["32"]
として書いた場合d.operator[]("32")
、オーバーロードの解決はオプション2を見ることすらなく、clangも正常にコンパイルされます。
編集:(質問の明確化)
これは過負荷解決の複雑な領域のようです。そのため、この場合の過負荷解決を詳細に説明し、標準を引用する回答をいただければ幸いです(不明である可能性が高い/高度なルールがある場合) 。
clangが正しければ、2つがあいまいである理由/一方が他方よりも優先されない理由を知ることにも興味があります。答えは、過負荷解決が2つの候補に含まれる暗黙の変換(ユーザー定義と標準の両方の変換)をどのように考慮するか、および一方が他方よりも優れていない理由を説明する必要があるでしょう。
注:演算子double()が演算子bool()に変更された場合、3つすべて(clang、vc、gcc)は、同様のあいまいなエラーでコンパイルを拒否します。