struct Y { }; struct X : std::tuple<Y> { }; int main() { std::get<0>(std::make_tuple(X{})); }
on wandbox
The above code compiles and works as expected with clang++ when using libC ++ .
When using libstdC ++ , the above code cannot compile with both clang++ and g++ with the following error:
include/c++/7.0.1/tuple:1302:36: error: no matching function for call to '__get_helper<0>(std::tuple<X>&)' { return std::__get_helper<__i>(__t); } ~~~~~~~~~~~~~~~~~~~~~~^~~~~ include/c++/7.0.1/tuple:1290:5: note: candidate: template<long unsigned int __i, class _Head, class ... _Tail> constexpr _Head& std::__get_helper(std::_Tuple_impl<_Idx, _Head, _Tail ...>&) __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept ^~~~~~~~~~~~ include/c++/7.0.1/tuple:1290:5: note: template argument deduction/substitution failed: include/c++/7.0.1/tuple:1302:36: note: 'std::_Tuple_impl<0, _Head, _Tail ...>' is an ambiguous base class of 'std::tuple<X>' { return std::__get_helper<__i>(__t); } ~~~~~~~~~~~~~~~~~~~~~~^~~~~ include/c++/7.0.1/tuple:1295:5: note: candidate: template<long unsigned int __i, class _Head, class ... _Tail> constexpr const _Head& std::__get_helper(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept ^~~~~~~~~~~~ include/c++/7.0.1/tuple:1295:5: note: template argument deduction/substitution failed: include/c++/7.0.1/tuple:1302:36: note: 'const std::_Tuple_impl<0, _Head, _Tail ...>' is an ambiguous base class of 'std::tuple<X>' { return std::__get_helper<__i>(__t); } ~~~~~~~~~~~~~~~~~~~~~~^~~~~
It seems that the libstdC ++ inheritance-based implementation of std::tuple is ambiguous when tuple elements get from std::tuple when calling std::get . I am inclined to think that this is an implementation defect in libstdc ++ - is that the case? Or is there something in the standard that will make a piece of code ill-formed?
source share