clang и gcc отличаются поведением для следующего кода:
struct foo
{
foo(int);
};
struct waldo
{
template <typename T>
operator T();
};
int main()
{
waldo w;
foo f{w};
}
Этот код принимается clang, при вызове конструктора foo(int)
. Однако gcc жалуется на двусмысленность между конструктором foo(int)
и неявно сгенерированными конструкциями копирования и перемещения:
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&&)
Кто прав?
Интересно также отметить, что если foo f{w}
изменено на foo f(w)
(обратите внимание на изменение от скобок до скобок), как gcc, так и clang дают ошибку. Это заставляет меня надеяться, что поведение gcc для приведенного выше примера (т.е. Предоставление ошибки) является правильным, иначе возникнет странная несогласованность между формами инициализации ()
и {}
.
EDIT: после предложения Kerrek SB я попробовал delete
создать конструктор копирования foo
:
struct foo
{
foo(int);
foo(const foo&) = delete;
};
Поведение остается неизменным.