22

次のコードでは、clang と gcc の動作が異なります。

struct foo
{
    foo(int);
};

struct waldo
{
    template <typename T>
    operator T();
};

int main()
{
    waldo w;
    foo f{w};
}

このコードは、clang によって受け入れられ、foo(int)コンストラクターが呼び出されます。foo(int)ただし、gcc は、コンストラクターと、暗黙的に生成されたコピー コンストラクターとムーブ コンストラクターとの間のあいまいさについて不平を言っています。

test.cpp: In function 'int main()':
test.cpp:15:12: error: call of overloaded 'foo(<brace-enclosed initializer list>)' is ambiguous
     foo f{w};
            ^
test.cpp:15:12: note: candidates are:
test.cpp:3:5: note: foo::foo(int)
     foo(int);
     ^
test.cpp:1:8: note: constexpr foo::foo(const foo&)
 struct foo
        ^
test.cpp:1:8: note: constexpr foo::foo(foo&&)

誰が正しいですか?

iffoo f{w}foo f(w)(中かっこからかっこへの変更に注意してください) に変更された場合、gcc と clang の両方でエラーが発生することにも注意してください。()これは、上記の例に対するgcc の動作 (つまり、エラーを与える) が正しいことを願ってい{}ます。

編集: Kerrek SBdeleteの提案に従って、次のコピー コンストラクターを試しましたfoo:

struct foo
{
    foo(int);
    foo(const foo&) = delete;
};

動作は同じままです。

4

1 に答える 1