struct Y { }; struct X : std::tuple<Y> { }; int main() { std::get<0>(std::make_tuple(X{})); } The above code compiles and works as expected with clang++ when using libc++.
The above code fails to compile with both clang++ and g++ when using libstdc++ 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 libstdc++'s inheritance-based implementation of std::tuple causes ambiguity when tuple elements derive from std::tuple upon calling std::get. I'm inclined to think that this is an implementation defect in libstdc++ - is that the case? Or is there something in the Standard that would make the code snippet ill-formed?