https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61947
Bug ID: 61947 Summary: Ambiguous calls when constructing std::tuple Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com #include <tuple> struct ConvertibleToAny { template <class T> operator T() const { return T(); } }; int main() { std::tuple<ConvertibleToAny&&> t(ConvertibleToAny{}); } Produces: third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4: error: call to constructor of '_Head_base<0UL, (anonymous namespace)::ConvertibleToAny &&, __empty_not_final<ConvertibleToAny &&>::value>' is ambiguous _Base(std::forward<_UHead>(__head)) { } ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4: note: in instantiation of function template specialization 'std::_Tuple_impl<0, (anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous namespace)::ConvertibleToAny, void>' requested here : _Inherited(std::forward<_UElements>(__elements)...) { } ^ experimental/users/romanp/tuple_bug/tuple-bug.cc:13:34: note: in instantiation of function template specialization 'std::tuple<(anonymous namespace)::ConvertibleToAny &&>::tuple<(anonymous namespace)::ConvertibleToAny, void>' requested here std::tuple<ConvertibleToAny&&> t(ConvertibleToAny{}); ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate is the implicit move constructor struct _Head_base<_Idx, _Head, false> ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate constructor (the implicit copy constructor) has been implicitly deleted third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:142:7: note: candidate constructor _Head_base(__uses_alloc0) The call shouldn't be ambiguous. It should pick the following constructor: [tuple.cnstr] template <class... UTypes> explicit tuple(UTypes&&... u); Requires: sizeof...(Types) == sizeof...(UTypes). is_constructible<Ti , Ui &&>::value is true for all i. Effects: Initializes the elements in the tuple with the corresponding value in std::forward<UTypes>(u). is_constructible<ConvertibleToAny&&, ConvertibleToAny&&>::value is true, so the precondition is satisfied. This bug affects std::bind as it's built on top of std::tuple. #include <functional> struct ConvertibleToAny { template <class T> operator T() const { return T(); } }; void Sink(int) {} int main() { std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{}); } Error: third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4: error: call to constructor of '_Head_base<0UL, (anonymous namespace)::ConvertibleToAny &&, __empty_not_final<ConvertibleToAny &&>::value>' is ambiguous _Base(std::forward<_UHead>(__head)) { } ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4: note: in instantiation of function template specialization 'std::_Tuple_impl<0, (anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous namespace)::ConvertibleToAny, void>' requested here : _Inherited(std::forward<_UElements>(__elements)...) { } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:868:14: note: in instantiation of function template specialization 'std::tuple<(anonymous namespace)::ConvertibleToAny &&>::tuple<(anonymous namespace)::ConvertibleToAny, void>' requested here { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/functional:1354:13: note: in instantiation of function template specialization 'std::forward_as_tuple<(anonymous namespace)::ConvertibleToAny>' requested here std::forward_as_tuple(std::forward<_Args>(__args)...), ^ experimental/users/romanp/tuple_bug/tuple-bug.cc:15:41: note: in instantiation of function template specialization 'std::_Bind<void (*(std::_Placeholder<1>))(int)>::operator()<(anonymous namespace)::ConvertibleToAny, void>' requested here std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{}); ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate is the implicit move constructor struct _Head_base<_Idx, _Head, false> ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate constructor (the implicit copy constructor) has been implicitly deleted third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:142:7: note: candidate constructor _Head_base(__uses_alloc0) ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:271:2: error: call to constructor of '_Head_base<0UL, (anonymous namespace)::ConvertibleToAny &&, __empty_not_final<ConvertibleToAny &&>::value>' is ambiguous _Base(std::forward<_Head>(_M_head(__in))) { } ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:409:17: note: in instantiation of member function 'std::_Tuple_impl<0, (anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl' requested here constexpr tuple(tuple&&) = default; ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/functional:1354:13: note: in instantiation of function template specialization 'std::forward_as_tuple<(anonymous namespace)::ConvertibleToAny>' requested here std::forward_as_tuple(std::forward<_Args>(__args)...), ^ experimental/users/romanp/tuple_bug/tuple-bug.cc:15:41: note: in instantiation of function template specialization 'std::_Bind<void (*(std::_Placeholder<1>))(int)>::operator()<(anonymous namespace)::ConvertibleToAny, void>' requested here std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{}); ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate is the implicit move constructor struct _Head_base<_Idx, _Head, false> ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate constructor (the implicit copy constructor) has been implicitly deleted third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:142:7: note: candidate constructor _Head_base(__uses_alloc0) ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:868:14: note: implicit move constructor for 'std::tuple<(anonymous namespace)::ConvertibleToAny &&>' first required here { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } ^ This bug appears to be a regression from libstdc++ 4.6, where the code was accepted.