After reading a large True Story article : Effective packaging I tried to implement a tuple on my own as an exercise:
#include <type_traits> #include <utility> #include <functional> template< std::size_t I, typename T > struct tuple_leaf { T value; }; template< std::size_t I, typename T > T & get(tuple_leaf< I, T > & leaf) { return leaf.value; } template< typename Is, typename ...Ts > struct tuple_base; template< std::size_t ...Is, typename ...Ts > struct tuple_base< std::index_sequence< Is... >, Ts... > : tuple_leaf< Is, Ts >... { using tuple_base_t = tuple_base; template< typename ...Args, typename = std::enable_if_t< (sizeof...(Ts) == sizeof...(Args)) > > tuple_base(Args &&... args) : tuple_leaf< Is, Ts >{std::forward< Args >(args)}... { ; } }; #if 0 template< typename ...Ts > struct tuple : tuple_base< std::index_sequence_for< Ts... >, Ts... > { using tuple_base_t = typename tuple::tuple_base_t; using tuple_base_t::tuple_base_t; using tuple_base_t::operator = ; }; #else // terse template< typename ...Ts > using tuple = tuple_base< std::index_sequence_for< Ts... >, Ts... >; #endif template< typename ...Args > tuple< Args &&... > forward_as_tuple(Args &&... args) { return {std::forward< Args >(args)...}; } #include <tuple> int main() { tuple< int > t(1); auto f = forward_as_tuple(t); (void)f; return 0; }
Real time example
After implementing forward_as_tuple I decided to change the definition of the tuple type from the template template to the alias template of my base class template, because all I need is to split the tuple class itself and its tuple_base implementation tuple_base just std::index_sequence_for for the template type template parameters. An alias package is exactly the right tool for this purpose. After that, I get an error ( #if 0 case):
error: call 'forward_as_tuple' is ambiguous
It seems strange to me because the alias pattern does nothing, and on the other hand, forward_as_tuple calls a type from the same namespace - I was hoping that ADL should work on the case discussed above.
How to explain the difference between #if 1 and #if 0 code versions?
source share