tupleの構造関数
6046 ワード
tupleの構造関数
template
class tuple :
public detail::map_tuple_to_cons
{
public:
typedef typename
detail::map_tuple_to_cons
inherited;//ベースクラス
typedef typename inherited::head_typehead_type;
//ベースクラスのhead_type(通常T 0、cons<>の定義を参照)
typedef typename inherited::tail_typetail_type;
//ベースクラスのtail_type(一般的にはcons<>)
//次は11個の構造関数があります.私は2個しか与えません.他のクラスは同じです.パラメータの個数が増加しただけです.
tuple(){}//ここでもベースクラスのデフォルトコンストラクタを呼び出します
//access_traits<>の定義は後述する
tuple(typename access_traits
:inherited(t 0,detail::cnull(),//cnull関数はnull_を返しますtype()オブジェクト
detail::cnull(),detail::cnull(),//detail::cnull()をnull_と見なすことができるtype()
detail::cnull(),detail::cnull(),
detail::cnull(),detail::cnull(),
detail::cnull(),detail::cnull())
{ }
tuple(typename access_traits
typename access_traits
: inherited(t0,t1, detail::cnull(), detail::cnull(),
detail::cnull(),detail::cnull(), detail::cnull(),
detail::cnull(),detail::cnull(), detail::cnull())
{ }
...
};
コンストラクション関数のパラメータ型はaccess_traits<>が表現するには理由があり、その定義は以下の通りである.
template
struct access_traits {
typedef const T& const_type;
typedef T&non_const_type;
typedef const typename boost::remove_cv
};
先にremove_cvはT型が持つ可能性のあるconstまたはvolatile修飾子を削除し、
そしてconst修飾子と参照を表す記号&、parameter_type.parameter_typeはtuple構造関数でパラメータ型として用いられる.
例えば、T 0のテンプレートパラメータをintとするとtypenameaccess_traits
なぜ参照型をパラメータ型として使用するのですか?
メリット:1、効率
2パラメータが参照の参照にならないようにする
参照をtuple内に直接保存したい場合は、T 0をint&に割り当てるとparameter_typeはアクセス_traitsは、次のような偏特化バージョンを用意しています.
template
typedef T& const_type;
typedef T& non_const_type;
typedef T¶meter_type;
};
注意:tupleが次のように定義できる理由も説明されています.
次のように使用できます.
tuple
アクセス:intj=std::get<0>(s);
std::tie(1, "aa", 2);
:
std::tuple<int&,string&, int&>
例:
次に、私たちの例に戻ると、tuple
A tuple(){}
B tuple(const int& t0) :inherited(t0, detail::cnull(),...,detail::cnull()){}
C tuple(const int& t0,const long& t1)
:inherited(t0,t1,detail::cnull(),...,detail::cnull())
{ }
D tuple(const int& t0,const long& t1,const bool& t2)
:inherited(t0,t1,t2,detail::cnull(),...,detail::cnull())
{ }
E tuple(const int& t0,const long& t1,const bool& t2,const null_type& t3)
: inherited(t0,t1,t2,detail::cnull(),..)
{}//これは使えません
...//その他のコンストラクション関数はこのように推す
以下の初期化方法があります.
tuple
tuple
tuple
tuple
このようにtupleを初期化するとします.
(1)与えられた初期化パラメータが十分である場合(すなわち、初期化パラメータが全て与えられている)に実パラメータがある場合は、実パラメータ初期化、すなわちhead(t)を用いる
tuple
tupleを呼び出すDコンストラクション関数が呼び出されます.
3つのパラメータをベースクラスに渡し、第1のcons<>はheadを10に割り当て、残りのパラメータをtailにすべて渡します.後者はcons<>で、headを11に割り当てます(この場合、最初のパラメータは11です).残りのtrueに後面の9つのnull_を加えます.typeはそのtail-cons
パラメータが最内層cons<>に伝達されると、少なくとも尾のある9つのnull_に違いない.type.
cons<>コンストラクション関数の「搾取」を経て、最内層cons<>のコンストラクション関数が呼び出されるまで、与えられたN個のパラメータは1つしか残っていません(他にも9個のnull_typeがあります).
(2)与えられた初期化パラメータが足りない場合(すなわち、初期化パラメータが全て与えられない)
実パラメータがない場合はhead()を使用して初期化
このように書くとします.
tuple
これはtupleのBコンストラクション関数を呼び出し、後者はこの一意のパラメータの後に9つのnull_を追加します.typeはベースクラスに渡されます.
最外層のcons<>は、最外層のcons<>がheadを10に初期化する.
10個のnullをtypeはtailの構造関数に渡される.
【後者のheadはlong型データメンバーであるため、最初のパラメータnull_typeでlong headメンバーを初期化し、コンパイルエラーを引き起こす】cons<>に別の構造関数を提供する.
template
cons(const null_type&t 1,//受け入れられた最初のパラメータがnull_typeの場合
T2& t2,T3& t3, T4& t4, T5& t5,
T6&t6, T7& t7, T8& t8, T9& t9, T10& t10 )
: head (), tail (t2, t3, t4, t5,t6, t7, t8, t9, t10, detail::cnull())
{}
初期化パラメータが「足りない」場合、cons<>のレイヤ(最後のレイヤ未満)で10個のパラメータがnull_だらけに「搾取」されます.typeは、cons<>のこのコンストラクション関数と一致し、head(t 1)ではなくheadをデフォルトで初期化します.
cons<>の偏特化バージョンにも似たようなバージョンがあります.
cons(const null_type&,
const null_type&, const null_type&, const null_type&,
const null_type&, const null_type&, const null_type&,
const null_type&, const null_type&, const null_type&)
: head () {}