Confusion on exiting std :: tuple cannot handle std :: get

My main idea was to get my own class from std :: tuple, to get some helper types inside:

template <typename ... T> class TypeContainer: public std::tuple<T...> { public: using BaseType = std::tuple<T...>; static const size_t Size = sizeof...(T); TypeContainer(T... args):std::tuple<T...>(args...){}; using index_sequence = std::index_sequence_for<T...>; }; 

Now I am trying to use the code as follows:

 using MyType_tuple_with_empty = std::tuple< std::tuple<float,int>, std::tuple<>, std::tuple<int>>; using MyType_typecontainer_with_empty = TypeContainer< TypeContainer<float,int>, TypeContainer<>, TypeContainer<int>>; using MyType_tuple_non_empty = std::tuple< std::tuple<float,int>, std::tuple<int>, std::tuple<int>>; using MyType_typecontainer_non_empty = TypeContainer< TypeContainer<float,int>, TypeContainer<int>, TypeContainer<int>>; template <typename T> void Do( const T& parms ) { // The following lines result in errors if TypeContainer with // empty element comes in. The empty element is in std::get<1> which // is NOT accessed here! std::cout << std::get<0>(std::get<0>(parms)) << " "; std::cout << std::get<1>(std::get<0>(parms)) << std::endl; std::cout << std::get<0>(std::get<2>(parms)) << std::endl; } int main() { MyType_tuple_with_empty p1{{ 1.2,3},{},{1}}; Do( p1 ); MyType_typecontainer_with_empty p2{{ 1.2,3},{},{1}}; Do( p2 ); // << this line raise the error MyType_tuple_non_empty p3{{ 1.2,3},{4},{1}}; Do( p3 ); MyType_typecontainer_non_empty p4{{ 1.2,3},{4},{1}}; Do( p4 ); } 

If I compiled with Do(p2) , I get the following error:

error: there is no corresponding function to call get(const TypeContainer<TypeContainer<float, int>, TypeContainer<>, TypeContainer<int> >&)

Can someone explain why the existence of an empty TypeContainer in connection with std::get will lead to this problem?

Edit: Additional information:

Lines

 MyType_tuple_with_empty p1{{{ 1.2,3},{},{1}}}; MyType_tuple_non_empty p3{{ 1.2,3},{4},{1}}; 

cannot compile with gcc5.2.0, but with gcc6.1.0. This is a little cryptic because I remember that the tuple constructor is really explicit. Why does this work with gcc6.1.0? But this is not the problem I'm looking for :-)

Another hint: The code I'm having problems with seems to be compiling with clang3.5.0.

A little hard to understand ...

Edit2: Digging through the error lists (long :-)) I found:

/opt/linux-gnu_5.2.0/include/++/5.2.0/tuple | 832 col 5 | note: template argument failed / replacement: main.cpp | 104 col 45 | note: ' std::tuple<_Elements ...> ' is the ambiguous base class ' TypeContainer<TypeContainer<float, int>, TypeContainer<>, TypeContainer<int> > ' || std::cout << std::get<0>(std::get<0>(parms)) << " " ;

It seems that in libg ++, someone is outputting multiple times from any type of tuple, which seems to be a broken library. Searching for this topic leads me to: Error of empty nested tuples

Is it really connected? Same error or new :-)

+6
source share
1 answer

Unfortunately, you need to add your containerized versions of get functions:

 template <std::size_t I, typename ...T> decltype(auto) get(TypeContainer<T...>&& v) { return std::get<I>(static_cast<std::tuple<T...>&&>(v)); } template <std::size_t I, typename ...T> decltype(auto) get(TypeContainer<T...>& v) { return std::get<I>(static_cast<std::tuple<T...>&>(v)); } template <std::size_t I, typename ...T> decltype(auto) get(TypeContainer<T...> const& v) { return std::get<I>(static_cast<std::tuple<T...> const&>(v)); } 

And just use get not std::get in the Do form of functions. The compiler can choose a namespace from the arguments.

I think I'm not sure if this is because gcc has EBO - Empty Base Optimization - implemented in its tuples. The exact reason is pretty hard to guess. You could report this to gcc bugzilla .


By the way, this is not a good habit to infer from STD classes. If you started with compilation, not inheritance, then you will need to provide your own get functions, and you will not notice this error, saving probably a lot of time.

+2
source

All Articles