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
ing конструктор копирования foo
:
struct foo
{
foo(int);
foo(const foo&) = delete;
};
Поведение остается прежним.
int
, так и вFoo
, так что это действительно выглядит двусмысленно. Однако попробуйте удалить или установить конструкторы копирования/перемещения по умолчанию и сравнить. - person Kerrek SB   schedule 17.04.2013