4

以下のコードを検討してください。

struct Bar{};

struct Foo
{
    Foo() = default;
    Foo(const Bar&) {}
    Foo(const Foo&) = delete;

    // IMPLICIT conversion to Bar
    operator Bar(){return {};}
};

int main() 
{
    Foo f1;
    Foo f2(static_cast<Bar>(f1)); // this is OK
    Foo f3(f1); // does not compile, why not implicit conversion to `Bar`?
}

このクラスには、 を受け入れるBarユーザー定義の変換演算子 toがあります。ただし、 の最後の行では、 に変換されてから に渡されると予想していました。ただし、削除されたコンストラクターのみが考慮されます。このコンストラクターの方が適していることは理解していますが、オーバーロード セットに も含まれていないのはなぜですか? また、コンパイラーが暗黙的な変換を実行しないのはなぜですか?FooBar&mainFoo f1BarFoo(const Bar&)Foo(const Foo&) = delete;Foo(const Bar&)

4

1 に答える 1

6

削除された定義が削除されたメンバー関数に記録される前に、ルックアップとオーバーロードの解決が行われるため、優先されます。

deleteつまり、オーバーロードの解決では、指定子と呼び出しが考慮されません。

Foo f3(f1);

f1が typeFooであるため、Foo(const Foo&)は直接パラメーターの型と一致します。したがって、 は よりもオーバーロード解決のランクが高くなりFoo(const Bar&)ます。

于 2015-11-18T21:43:02.267 に答える