
On 4/26/05, Larry Evans <cppljevans@cox-internet.com> wrote:
On 04/26/2005 04:18 AM, Giovanni P. Deretta wrote:
Hi,
I have been using a small extension to the tuple library 'get' function, that I have found very handy. It allows the extraction of an element of a tuple by specifying its type instead of the index. Example:
given the tuple boost::tuple<type1, type2, type3>
get<type1> returns the first element of the tuple of that type.
This allows one to write more self describing code: you don't need to look up the tuple element type when you find an indexed get function buried deep inside some code. This is especially useful with nested tuples where for example looks more like line noise than real code :).
Of course this wouldn't work for this tuple:
tuple<type1, type1, type3>
Well, get<type1>(my_tuple) would return the first element of that type (actually my code will return the *last* element, but as I said, it was just a quick hack). Anyway, the get<type> form is most useful with tuples containing elements of different type. In practice you overload the meaning of the type to also be a an element tag. This way tuples become as powerful as structures: you can access element by "name". They are more powerful actually, as they have introspection capability: elements can be enumerated. Also the possibility of accessing tuple elements indipendently of the exact tuple type and element position can be very handy in generic programming. The get<type> form that i proposed can be easily added with zero changes to the existing tuple code/interface. A more complex addition would allow the association of a tag to each tuple element i.e.: tuple<mpl::list<element1_type, element1_tag>, mpl::list<element2_type, element2_tag>,.....> a get<elementn_tag> would return the nth element. This would make the tag unique and maybe open new possibilities. BTW, tuples containing many objects of the same type are better seen as containers, thus the indexed get is fine.
Maybe if there were some way of associating an enumeration with the tuple, you could:
get<f_i>(my_tuple)
where fi is some enumerator in, e.g.:
enum my_tuple_fields { f_0 , f_1 ... , f_n };
but even then, with nested tuples, there's a possible name conflict amoung the enumerators. Possibly the enumerator names could contain a prefix indicating to which type they belong:
enum type0_fields { t0_f_0 , t0_f_1 ... , t0_f_n0 };
enum type1_fields { t1_f_0 , t1_f_1 ... , t1_f_n1 };
In a theoretical extended_tuple, the enum could be part of the tuple itself, so you could do 'get<my_tuple.element1> (my_tuple)' and there would not be no name conflict. The problem with enums is that you have to maintain them separately: this is information duplication that could easily go out of sync. -- Giovanni P. Deretta