in here http://en.cppreference.com/w/cpp/utility/tuple/tuple_element given possible implementation of std::tuple_element.
template< std::size_t I, class T >
struct tuple_element;
// recursive case
template< std::size_t I, class Head, class... Tail >
struct tuple_element<I, std::tuple<Head, Tail...>>
: std::tuple_element<I-1, std::tuple<Tail...>> { };
// base case
template< class Head, class... Tail >
struct tuple_element<0, std::tuple<Head, Tail...>> {
typedef Head type;
};
But, this implementation need deep recursion instantiation, if tuple has a lot parameters ( more that 100 or 200 parameters).
Q1: Why C++11 was not added special operator for getting elements by index? like tuple[2] or tuple[0] ?
Q2: Is possible reduce the deep instantiation? For example in D language more template algorithms (in typetuple) needed O(log(N) ) deep instantiation.
EDIT: Q1: Why C++11 was not added special operator for getting elements by index from variadic templates? like template< class ...T> struct index{ typedef T[3] third_element;}
First, because even if they did, it'd still work the same way: with recursion. Tuples are primarily a library feature. Though they piggy-back off of language features like variadic templates, they were more or less functional in C++98/03.
Second, that would not be possible. Not without a very difficult language change.
It's not clear what you mean by
tuple[2]
.If you mean that
std::tuple<int, float, std::string>[2]
should somehow resolve to the typenamestd::string
, then that means you now need to explain why this works. Again, tuples are a library feature, not a language construct. So there would have to be some language construct wherebytypename[integer]
is a valid construct. What would that be and what would it mean?If you mean that given:
We should be able to get the string with
tpl[2]
, that's several shades of "not going to happen". C++ is a statically typed language. The only reasonstd::get
is able to get away with what it does is that the integer index is not a function parameter; it is a template parameter. That is what allowsstd::get<0>
to return a completely different type fromstd::get<2>
. That can't happen withoperator[](int)
; that function must always return the same type.So now you'd need to have something like
template<class T, int i> ... operator[]()
. And that would be very confusing, because you can no longer dotpl[runtimeValue]
on that type (since template parameters must be compile-time values). There is no such type whereoperator[]
is restricted from being able to work on runtime values. So you'd be creating a very oddball type.And even then... it would still have to do recursion to get the value.
Outside of compile times (which is not an unreasonable issue), what does it matter? A decent inliner will throw most of them away.
As for compile times, there are non-recursive implementations of various features of
std::tuple
. Whether they can dotuple_element
non-recursively, I don't think so. This libc++ implementation seems to suggest that it can't, despite implementing thetuple
itself non-recursively.