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