Download presentation
Presentation is loading. Please wait.
1
By Per Bleshøy Nielsen & Bergur Ziska
Tuple Types By Per Bleshøy Nielsen & Bergur Ziska
2
What is a tuple? A collection of values.
Value types can be of same type or may vary. Alternatives: - Arrays - Structs - Reference/pointer arguments
3
Why tuples? Overcome the limitation of a single return value.
Avoid extensive use of pointer / reference parameters. An in-code way of defining small structs.
4
The Duo We start out with a Duo, which binds a pair of values.
This will be the building block for tuples.
5
Duo example template <typename T1, typename T2> class Duo { public: T1 v1; // value of first field T2 v2; // value of second field // constructors Duo () : v1(), v2() {} Duo (T1 const& a, T2 const& b) : v1(a), v2(b) {} }; int main() { Duo<bool,int> result; result.v1 = true; result.v2 = 42; return 0; }
6
Recursive Duos We can now use recursion to deal with larger collections of data: Duo<bool,Duo<int,Duo<double, char*> > > result; result.v1 = false; result.v2.v1 = 42; result.v2.v2.v1 = 7.0; result.v2.v2.v2 = ”benny”; Cumbersome access to members We would like a generic way to access members.
7
The val function // primary template for value of Nth field of (duo) T template < int N, typename T > struct DuoValue { static void get( T& ) { } }; // specialization for 1st field of plain duo template < typename A, typename B > struct DuoValue< 1, Duo< A, B > > { static A& get( Duo< A, B > &d ) { return d.v1; } }; // specialization for Nth field of recursive duo template < int N, typename A, typename B, typename C > struct DuoValue< N, Duo< A, Duo< B, C > > > { static TypeOp< typename DuoT< N-1, Duo< B, C> >::ResultT >::RefT get( Duo< A, Duo< B, C > > &d ) { return DuoValue< N-1, Duo< B, C> >::get( d.v2 ); } };
8
Easier member access So we implement the val() function using DuoValue: template <int N, typename A, typename B> inline typename TypeOp< typename DuoT<N, Duo<A, B> >::ResultT>::RefT val( Duo<A, B>& d ) { return DuoValue< N, Duo< A, B > >::get( d ); } Now we are able to access members as: Duo< bool, Duo< int, Duo< double, char* > > > result; val<0>(result) = false; val<1>(result) = 42; val<2>(result) = 7.0; val<3>(result) = ”benny”; This eases member access but construction is still cumbersome for large recursive duos
9
Tuples // type that represents unused type parameters class NullT {};
// Tuple<> in general derives from Tuple<> with one more NullT template <typename P1, typename P2 = NullT, typename P3 = NullT, typename P4 = NullT> struct Tuple : public Duo<P1, typename Tuple<P2,P3,P4,NullT>::BaseT> { typedef Duo<P1, typename Tuple<P2,P3,P4,NullT>::BaseT> BaseT; Tuple() {} Tuple(typename TypeOp<P1>::RefConstT a1, typename TypeOp<P2>::RefConstT a2, typename TypeOp<P3>::RefConstT a3 = NullT(), typename TypeOp<P4>::RefConstT a4 = NullT()) : BaseT(a1, Tuple<P2,P3,P4,NullT>(a2,a3,a4)) { } };
10
Tuples - specialization
// specialization to end deriving recursion template <typename P1, typename P2> class Tuple<P1,P2,NullT,NullT> : public Duo<P1,P2> { public: typedef Duo<P1,P2> BaseT; Tuple() {} Tuple(typename TypeOp<P1>::RefConstT a1, typename TypeOp<P2>::RefConstT a2, typename TypeOp<NullT>::RefConstT = NullT(), typename TypeOp<NullT>::RefConstT = NullT()) : BaseT(a1, a2) { } }; There is also a specialization for singeltons
11
Pros & cons Fast to write, inplace construction Little or no overhead
No descriptive member names Arbitrary size limit, depending on implementation
12
Sources Vandevoorde, Josuttis: C++ Templates – The Complete Guide
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.