c++ - Confused by Tuple example in TC++PL 4th Edition -
i'm having trouble working out how code works.
i have shorter version of example here, think qualifies fair use:
#include <typeinfo> #include <iostream> using namespace std; struct nil{}; // primary template. template<typename t1=nil, typename t2=nil> struct tuple : tuple<t2> { t1 x; using base = tuple<t2>; base* base() { return static_cast<base*>(this); } const base* base() const { return static_cast<const base*>(this); } tuple(const t1& t1, const t2& t2) : base{t2}, x{t1} { } }; // specialization. template<> struct tuple<> { tuple() {} }; // specialization. template<typename t1> struct tuple<t1> : tuple<> { t1 x; using base = tuple<>; base* base() { return static_cast<base*>(this); } const base* base() const { return static_cast<const base*>(this); } tuple(const t1& t1) : base{}, x{t1} { } }; template<typename t1, typename t2> void print_elements(ostream& os, const tuple<t1,t2>& t) { os << t.x << ", "; print_elements(os,*t.base()); } template<typename t1> void print_elements(ostream& os, const tuple<t1>& t) { os << t.x; } template<> void print_elements(ostream& os, const tuple<>& t) { os << " "; } template<typename t1, typename t2> ostream& operator<<(ostream& os, const tuple<t1,t2>& t) { os << "t1: " << typeid(t1).name() << ", t2: " << typeid(t2).name() << "\n"; os << "{ "; print_elements(os,t); os << " }"; return os; } int main() { cout << tuple<double, int>{1.1, 22} << "\n"; cout << tuple<double>{1.1} << "\n"; cout << tuple<>{} << "\n"; }
the output of program (from stacked-crooked)
t1: d, t2: { 1.1, 22 } t1: d, t2: 3nil { 1.1 } t1: 3nil, t2: 3nil { }
there 1 definition of operator<< (for primary template).
this can called tuple<> , tuple. way understand means call operator<< tuple , tuple.
secondly, when invoked tuple defaulted (nil) types, calls correct print_elements. why not call print_elements output nil values?
i added operator<< nil , doesn't change behaviour.
thanks!
that how works print_elements
. there overload tuple
of 2 elements, tuple
1 element (second nil) , overload tuple
0 elements (both nil).
in operator <<
:
when t
tuple<t1, t2>
, print_elements<tuple<t1, t2> >
called;
when t
tuple<t1>
(really tuple<t1, nil>
), print_elements<tuple<t1> >
called, since version better, print_elements<tuple<t1, t2> >
, t2
nil
;
when t
tuple<>
(really tuple<nil, nil>
), print_elements<tuple<> >
called, since version better, versions.
Comments
Post a Comment