https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66338
Bug ID: 66338 Summary: std::forward_as_tuple() issue with single argument Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ptomulik at meil dot pw.edu.pl Target Milestone: --- Created attachment 35652 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35652&action=edit Minimal example Hi, this example fails to compile (it compiles in clang however): //////////////////// fail1.cpp /////////////////////////// #include <tuple> struct S { int i_; template<typename T> S(T&& i) noexcept(noexcept(i_ = i)) { i_ = i; } S() noexcept : i_{0} {}; }; int main() { std::tuple<S&&>(std::forward_as_tuple(S{})); return 0; } //////////////////// fail1.cpp /////////////////////////// with the following error message: g++ -Wall -Wextra -Werror -pedantic -g -O0 -std=c++11 -o test-gcc test.cpp test.cpp: In instantiation of ‘S::S(T&&) [with T = std::tuple<S&&>]’: /usr/include/c++/4.9/type_traits:1401:39: required by substitution of ‘template<class _From1, class _To1, class> static std::true_type std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = std::tuple<S&&>; _To1 = S&&; <template-parameter-1-3> = <missing>]’ /usr/include/c++/4.9/type_traits:1410:30: required from ‘struct std::__is_convertible_helper<std::tuple<S&&>, S&&, false>’ /usr/include/c++/4.9/type_traits:1416:12: required from ‘struct std::is_convertible<std::tuple<S&&>, S&&>’ /usr/include/c++/4.9/type_traits:129:12: required from ‘struct std::__and_<std::is_convertible<std::tuple<S&&>, S&&> >’ /usr/include/c++/4.9/tuple:402:40: required by substitution of ‘template<class ... _UElements, class> constexpr std::tuple< <template-parameter-1-1> >::tuple(_UElements&& ...) [with _UElements = {std::tuple<S&&>}; <template-parameter-1-2> = <missing>]’ test.cpp:16:45: required from here test.cpp:8:26: error: cannot convert ‘std::tuple<S&&>’ to ‘int’ in assignment noexcept(noexcept(i_ = i)) If I remove the noexcept(noexcept(i_ = i)) or invoke forward_as_tuple() with two arguments, then it compiles without a problem. ///////////////////////////// ok1.cpp //////////////////////////// #include <tuple> struct S { int i_; template<typename T> S(T&& i) // noexcept(noexcept(i_ = i)) { i_ = i; } S() noexcept : i_{0} {}; }; int main() { std::tuple<S&&>(std::forward_as_tuple(S{})); return 0; } ///////////////////////////// ok1.cpp //////////////////////////// ///////////////////////////// ok2.cpp //////////////////////////// #include <tuple> struct S { int i_; template<typename T> S(T&& i) noexcept(noexcept(i_ = i)) { i_ = i; } S() noexcept : i_{0} {}; }; int main() { std::tuple<S&&,S&&>(std::forward_as_tuple(S{}, S{})); return 0; } ///////////////////////////// ok2.cpp //////////////////////////// Attached an example which fails to compile (fail1.cpp).