Calling `std::get` on `std::tuple` with elements deriving from `std::tuple` - ill-formed?
Asked Answered
C

1

7
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++.

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?

Classicize answered 1/2, 2017 at 21:55 Comment(1)
gcc.gnu.org/bugzilla/show_bug.cgi?id=71096Altogether
C
2

As mentioned by T.C. in the comments, this is caused by the known bug #71096.

Classicize answered 2/4, 2017 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.