打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c++ Template Tuple?元组

c++ Template Tuple 元组


#ifndef __TUPLE2_H
#define __TUPLE2_H
#include "duo.h"




class NullT
{


};


template<typename P1,typename P2 = NullT,typename P3= NullT,typename P4 = NullT,typename P5 =NullT>
class Tuple
: public Duo<P1,typenameTuple<P2,P3,P4,P5,NullT>::BaseT>
{
public:
typedef Duo<P1,typenameTuple<P2,P3,P4,P5,NullT>::BaseT> BaseT;


Tuple()
{


}


Tuple(
  TypeOp<P1>::RefConstTa1,
  TypeOp<P2>::RefConstTa2,
  TypeOp<P3>::RefConstTa3 = NullT(),
  TypeOp<P4>::RefConstTa4 = NullT(),
  TypeOp<P5>::RefConstTa5 = NullT()
  ):BaseT(a1,Tuple<P2,P3,P4,P5,NullT>(a2,a3,a4,a5))
{


}
protected:
private:
};


template<typename P1,typenameP2>
class Tuple<P1,P2,NullT,NullT,NullT>:public Duo<P1,P2>
{
public:
typedef Duo<P1,P2>BaseT;
Tuple()
{


}
Tuple(TypeOp<P1>::RefConstTa1,
TypeOp<P2>::RefConstTa2,
TypeOp<NullT>::RefConstT =NullT(),
TypeOp<NullT>::RefConstT =NullT(),
TypeOp<NullT>::RefConstT =NullT()
): BaseT(a1,a2)
{
}

};


template <typename P1>
classTuple<P1,NullT,NullT,NullT,NullT> :public Duo<P1,void>
{
public:
    typedefDuo<P1,void> BaseT;
    Tuple()
    {}
    Tuple(typenameTypeOp<P1>::RefConstT a1,
typenameTypeOp<NullT>::RefConstT =NullT(),
typenameTypeOp<NullT>::RefConstT =NullT(),
typenameTypeOp<NullT>::RefConstT =NullT(),
typenameTypeOp<NullT>::RefConstT =NullT())
: BaseT(a1)
    {}
}
;


// convenience function for 1 argument
template <typename T1>
inline Tuple<T1> make_tuple(T1 const&a1)
{
    returnTuple<T1>(a1);
}


// convenience function for 2 arguments
template <typename T1, typenameT2>
inline Tuple<T1,T2> make_tuple(T1const &a1, T2 const &a2)
{
    returnTuple<T1,T2>(a1,a2);
}


// convenience function for 3 arguments
template <typename T1, typename T2, typenameT3>
inline Tuple<T1,T2,T3> make_tuple(T1const &a1, T2 const &a2,
                          T3 const &a3)
{
    returnTuple<T1,T2,T3>(a1,a2,a3);
}


// convenience function for 4 arguments
template <typename T1, typename T2, typename T3,typename T4>
inline Tuple<T1,T2,T3,T4>make_tuple(T1 const &a1, T2 const&a2,
                              T3const &a3, T4 const &a4)
{
    returnTuple<T1,T2,T3,T4>(a1,a2,a3,a4);
}


// convenience function for 5 arguments
template <typename T1, typename T2, typenameT3,typename T4, typename T5>
inline Tuple<T1,T2,T3,T4,T5>make_tuple(T1 const &a1, T2 const&a2,
                                T3 const &a3, T4 const &a4,
                                T5 const &a5)
{
    returnTuple<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
}
#endif
以上是Tuple定义和使用内联函数.


#ifndef _DUO_H
#define _DUO_H
#include "Typeof.h"
template <typename T1, typenameT2>
class Duo
{
public:
    typedefT1 Type1;  // type of firstfield
    typedefT2 Type2;  // type of secondfield
    enum{ N = 2};    //number of fields

private:
    T1value1;        // value of first field
    T2value2;        // value of second field

public:
    //constructors
    Duo(): value1(), value2()
    {}
    Duo(T1 const & a, T2 const & b)
: value1(a), value2(b)
    {}

    //for implicit type conversion during construction
    template<typename U1, typename U2>
Duo (Duo<U1,U2> const& d)
: value1(d.v1()), value2(d.v2())
    {}

    //for implicit type conversion during assignments
    template<typename U1, typename U2>
Duo<T1, T2>&operator = (Duo<U1,U2> const& d)
    {
        value1= d.value1;
        value2= d.value2;
        return*this;
    }

    //field access
    T1&v1()
    {
        returnvalue1;
    }
    T1const& v1() const
    {
        returnvalue1;
    }


    T2&v2()
    {
        returnvalue2;
    }
    T2const& v2() const
    {
        returnvalue2;
    }
};


// comparison operators (allow mixed types):
template <typename T1, typename T2,
typename U1, typename U2>
inline
bool operator == (Duo<T1,T2>const& d1, Duo<U1,U2>const& d2)
{
    returnd1.v1()==d2.v1() &&d1.v2()==d2.v2();
}


template <typename T1, typename T2,
typename U1, typename U2>
inline
bool operator != (Duo<T1,T2>const& d1, Duo<U1,U2>const& d2)
{
    return!(d1==d2);
}


// convenience function for creation and initialization
template <typename T1, typenameT2>
inline
Duo<T1,T2> make_duo (T1 const& a, T2 const & b)
{
    returnDuo<T1,T2>(a,b);
}


template <typename A, typename B, typenameC>
class Duo<A, Duo<B,C>>
{
public:
    typedefA        T1;          // type of first field
    typedefDuo<B,C>T2;          // type of second field
    enum{ N = Duo<B,C>::N + 1};  // number of fields

private:
    T1value1;        // value of first field
    T2value2;        // value of second field

public:
    //constructors
    Duo(): value1(), value2()
    {}
    Duo(T1 const & a, T2 const & b)
: value1(a), value2(b)
    {}

    //for implicit type conversion during construction
    template<typename U1, typename U2>
Duo (Duo<U1,U2> const& d)
: value1(d.v1()), value2(d.v2())
    {}

    //for implicit type conversion during assignments
    template<typename U1, typename U2>
Duo<T1, T2>&operator = (Duo<U1,U2> const& d)
    {
        value1= d.value1;
        value2= d.value2;
        return*this;
    }

    //field access
    T1&v1()
    {
        returnvalue1;
    }
    T1const& v1() const
    {
        returnvalue1;
    }


    T2&v2()
    {
        returnvalue2;
    }
    T2const& v2() const
    {
        returnvalue2;
    }
};




template <int N, typename T>
class DuoT
{
public:
    typedefvoidResultT;    //in general, the result type is void
};


// specialization for 1st field of a plain duo
template <typename A, typenameB>
class DuoT<1, Duo<A,B>>
{
public:
    typedefA ResultT;
};


// specialization for 2nd field of a plain duo
template <typename A, typenameB>
class DuoT<2, Duo<A,B>>
{
public:
    typedefB ResultT;
};


// specialization for Nth field of a recursive duo
template <int N, typename A, typename B, typenameC>
class DuoT<N, Duo<A,Duo<B,C> >>
{
public:
    typedeftypename DuoT<N-1,Duo<B,C> >::ResultTResultT;
};


// specialization for 1st field of a recursive duo
template <typename A, typename B, typenameC>
class DuoT<1, Duo<A,Duo<B,C> >>
{
public:
    typedefA ResultT;
};


// specialization for 2nd field of a recursive duo
template <typename A, typename B, typenameC>
class DuoT<2, Duo<A,Duo<B,C> >>
{
public:
    typedefB ResultT;
};




template <int N, typename T>
class DuoValue
{
public:
    staticvoid get
        (T&)
           //in general, we have no value
    }
    staticvoid get
        (Tconst&)
    {}
}
;


// specialization for 1st field of a plain duo
template <typename A, typenameB>
class DuoValue<1, Duo<A,B> >
{
public:
    staticA& get
        (Duo<A,B> &d)
    {
        returnd.v1();
    }
    staticA const& get
        (Duo<A,B> const &d)
    {
        returnd.v1();
    }
};


// specialization for 2nd field of a plain duo
template <typename A, typenameB>
class DuoValue<2, Duo<A,B> >
{
public:
    staticB& get
        (Duo<A,B> &d)
    {
        returnd.v2();
    }
    staticB const& get
        (Duo<A,B> const &d)
    {
        returnd.v2();
    }
};


// specialization for Nth field of recursive duo
template <int N, typename A, typename B, typenameC>
struct DuoValue<N, Duo<A,Duo<B,C> >>
{
    static
    typenameTypeOp<typename DuoT<N-1,Duo<B,C>>::ResultT>::RefT
    get
        (Duo<A,Duo<B,C> >&d)
    {
        returnDuoValue<N-1, Duo<B,C>>::get
                  (d.v2());
    }


    statictypename TypeOp<typename DuoT<N-1,Duo<B,C>
    >::ResultT>::RefConstT
    get
        (Duo<A,Duo<B,C> > const&d)
    {
        returnDuoValue<N-1, Duo<B,C>>::get
                  (d.v2());
    }
};


// specialization for 1st field of recursive duo
template <typename A, typename B, typenameC>
class DuoValue<1, Duo<A,Duo<B,C> >>
{
public:
    staticA& get
        (Duo<A,Duo<B,C> >&d)
    {
        returnd.v1();
    }
    staticA const& get
        (Duo<A,Duo<B,C> > const&d)
    {
        returnd.v1();
    }
};


// specialization for 2nd field of recursive duo
template <typename A, typename B, typenameC>
class DuoValue<2, Duo<A,Duo<B,C> >>
{
public:
    staticB& get
        (Duo<A,Duo<B,C> >&d)
    {
        returnd.v2().v1();
    }
    staticB const& get
        (Duo<A,Duo<B,C> > const&d)
    {
        returnd.v2().v1();
    }
};


template <int N, typename A, typenameB>
inline
typename TypeOp<typename DuoT<N,Duo<A, B>>::ResultT>::RefT
val(Duo<A, B>&d)
{
    returnDuoValue<N, Duo<A, B>>::get
(d);
}


// return Nth value of constant duo
template <int N, typename A, typenameB>
inline
typename TypeOp<typename DuoT<N,Duo<A, B>>::ResultT>::RefConstT
val(Duo<A, B> const&d)
{
    returnDuoValue<N, Duo<A, B>>::get
(d);
}




template <typename A>
struct Duo<A,void>
{
public:
    typedefA    T1;  //type of first field
    typedefvoid T2;  // type of secondfield
    enum{ N = 1 };   // number offields

private:
    T1value1;        //value of first field

public:
    //constructors
    Duo(): value1()
    {}
    Duo(T1 const & a)
: value1(a)
    {}

    //field access
    T1&v1()
    {
        returnvalue1;
    }
    T1const& v1() const
    {
        returnvalue1;
    }

    voidv2()
    {}
    voidv2() const
{}
    //...
}
;
#endif


测试:
#include <iostream>
#include <string>
#include "duo.h"
#include "tuple.h"
using namespace std;


Duo<float,int> foo ()
{
    returnmake_duo(42,42);
}






int main1()
{
    //create and use simple duo
    Duo<bool,int>d;
    std::cout<< d.v1()<< std::endl;
    std::cout<<val<1>(d)<< std::endl;

    //create and use triple
    Duo<bool,Duo<int,float>> t;

    val<1>(t)= true;
    val<2>(t)= 42;
    val<3>(t)= 0.2;

    std::cout<<val<1>(t)<< std::endl;
    std::cout<<val<2>(t)<< std::endl;
    std::cout<<val<3>(t)<< std::endl;


Duo<bool,Duo<int,Duo<float,char>> > temp;

    val<1>(temp)= true;
    val<2>(temp)= 42;
    val<3>(temp)= 0.2;
val<4>(temp) = 'A';

    std::cout<<val<1>(temp)<< std::endl;
    std::cout<<val<2>(temp)<< std::endl;
    std::cout<<val<3>(temp)<< std::endl;
std::cout <<val<4>(temp)<< std::endl;


Duo<bool,Duo<int,Duo<float,string>> > temp1;

    val<1>(temp1)= true;
    val<2>(temp1)= 42;
    val<3>(temp1)= 0.2;
val<4>(temp1) = "helloworld";

    std::cout<<val<1>(temp1)<< std::endl;
    std::cout<<val<2>(temp1)<< std::endl;
    std::cout<<val<3>(temp1)<< std::endl;
std::cout <<val<4>(temp1)<< std::endl;
return 0;
}


int main()
{
    //create and use tuple with only one field
    Tuple<int>t1;
    val<1>(t1)+= 42;
    std::cout<< t1.v1()<< std::endl;

    //create and use duo
    Tuple<bool,int>t2;
    std::cout<<val<1>(t2)<< ", ";
    std::cout<< t2.v1()<< std::endl;

    //create and use triple
    Tuple<bool,int,double>t3;

    val<1>(t3)= true;
    val<2>(t3)= 42;
    val<3>(t3)= 0.2;

    std::cout<<val<1>(t3)<< ", ";
    std::cout<<val<2>(t3)<< ", ";
    std::cout<<val<3>(t3)<< std::endl;

    t3= make_tuple(false, 23, 13.13);

    std::cout<<val<1>(t3)<< ", ";
    std::cout<<val<2>(t3)<< ", ";
    std::cout<<val<3>(t3)<< std::endl;

    //create and use quadruple
    Tuple<bool,int,float,double>t4(true,42,13,1.95583);
    std::cout<<val<4>(t4)<< std::endl;
    std::cout<< t4.v2().v2().v2()<< std::endl;
return 0;
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Tuple 用法详解
C++雾中风景16:std::make_index_sequence, 来试一试新的黑魔法吧
【洛谷日报#130】动态DP入门
C++17新属性详解
C++11新特性
C++14新特性的所有知识点全在这儿啦
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服