tuple這玩意實現方法就是遞歸方式展開函數包的完美示例。相關文章可以查看<深入應用C++11>3.2.1.1章節。
tuple的實現思想可以查看侯捷老師視頻:https://www.bilibili.com/video/BV1p4411v7Dh?p=20
假如我們現在有如下源碼:
tuple<int, double, char*> my_tuple = make_tuple(1,2.2,"love")
好吧來看 VS2013實現源碼:
// CLASS tuple這裏是前置聲明
template<class... _Types>
class tuple;
template<>//這裏是特化版本,爲了中止繼承
class tuple<>
{
//這裏沒有成員函數,什麼都不存
}
//這裏是真正普通模板類
template<class _This,//_This 就對應我們上面例子中的1對應的 int 類型
class... _Rest> //_Rest 就對應 double 和 char* 組成的一包
class tuple<_This, _Rest...>
: private tuple<_Rest...>//這裏繼承於自己,當然也不是自己,因爲模板參數不一樣
{
public:
typedef _This _This_type;
typedef tuple<_This, _Rest...> _Myt;
typedef tuple<_Rest...> _Mybase;
static const size_t _Mysize = 1 + sizeof...(_Rest);
_Tuple_val<_This> _Myfirst; // the stored element//這裏存放第一個int類型的1
}
// CLASS tuple_element
template<size_t _Index, class _Tuple>
struct tuple_element;
template<class _This,class... _Rest>
struct tuple_element<0, tuple<_This, _Rest...> >
{ // select first element
typedef _This type;
typedef typename add_lvalue_reference<const _This>::type _Ctype;
typedef typename add_lvalue_reference<_This>::type _Rtype;
typedef typename add_rvalue_reference<_This>::type _RRtype;
typedef tuple<_This, _Rest...> _Ttype;
};
template<size_t _Index, class _This,class... _Rest>
struct tuple_element<_Index, tuple<_This, _Rest...> >//這裏tuple也會拆包,直到_Index爲0,此時我們想要取的值,爲此類型tuple的成員變量。
: public tuple_element<_Index - 1, tuple<_Rest...> >//這裏_Index 會遞減,直到第一個模板參數爲0
{ // recursive tuple_element definition
};
// FUNCTION get
template<size_t _Index, class... _Types> inline
typename tuple_element<_Index, tuple<_Types...> >::_Rtype//這裏會根據_Types進行遞減
get(tuple<_Types...>& _Tuple)//根據這裏的_Tuple能夠推導出tuple的一包參數_Types
{ // get reference to _Index element of tuple
typedef typename tuple_element<_Index, tuple<_Types...> >::_Ttype _Ttype;
return (((_Ttype&)_Tuple)._Myfirst._Val);//_Ttype是存着我們那個值的基類,強轉即可
}
編譯器編程可以運行期編程難多了。如果是運行期,可能會這樣:get(0),而編譯器是這樣get<0>()。妙哉妙哉。
// CLASS _Ignore
class _Ignore
{ // class that ignores assignments
public:
_Ignore()
{ // construct
}
template<class _Ty>//任何類型變量都可以賦值給此類型變量
void operator=(const _Ty&) const
{ // do nothing
}
};
const _Ignore ignore;
// FUNCTION tie
template<class... _Types> inline
tuple<_Types&...>
tie(_Types&... _Args) _NOEXCEPT
{ // make tuple from elements
typedef tuple<_Types&...> _Ttype;
return (_Ttype(_Args...));//這裏很簡單就是把原tuple包賦值給現tuple包。
}