https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87676
Bug ID: 87676 Summary: Presence of variadic constructor template breaks overload resolution for other constructors Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: harald at gigawatt dot nl Target Milestone: --- Reduced testcase: struct S1 { S1(int, int, int); }; struct S2 { S2(const S2 &) = delete; S2(const S1 &); S2(S1 &&); template <typename...T> S2(T &&...); }; S2 s({1, 2, 3}); I expect this to compile using the S2(S1 &&) constructor. Instead, GCC emits an error: test.cc:8:15: error: call of overloaded ‘S2(<brace-enclosed initializer list>)’ is ambiguous S2 s({1, 2, 3}); ^ test.cc:5:3: note: candidate: ‘S2::S2(S1&&)’ S2(S1 &&); ^~ test.cc:4:3: note: candidate: ‘S2::S2(const S1&)’ S2(const S1 &); ^~ test.cc:3:3: note: candidate: ‘S2::S2(const S2&)’ <deleted> S2(const S2 &) = delete; ^~ That is, ambiguous between the three non-template constructors. But if the constructor template is commented out, GCC no longer sees it as ambiguous, GCC does prefer the S2(S1 &&) overload. I do not understand why the presence of a constructor template would affect the overload resolution between the other constructors. FWIW, clang behaves the same way as GCC, which is a sign that there might be a good reason for the current behaviour, but MSVC and Intel do accept the code.