tuple實現原理

tuple實現原理

C++從11標準開始就引入了一個tuple元組,這種類型很方便的存儲各種不同類型的元素;我們知道在C++中,都需要一個唯一確定的類型才能定義一個變量和分配內存結構,那麼tuple具體是怎麼實現的呢?

1. 可變參數的模板

我們來看一個代碼:

void printx()
{
}
template<typename Type, typename... Types>
void printx(const Type& arg1, const Types&... args)
{
	std::cout << arg1 << std::endl;
	std::cout << "args: " << sizeof...(args) << std::endl;
	printx(args...);
}

int main(int args, char* argv[])
{
	printx(100, "hello", "world", 3.14, 200);
	return 0;
}

這個程序的輸出爲:

100
args: 4
hello
args: 3
world
args: 2
3.14
args: 1
200
args: 0

如果不瞭解C++11 模板特性的童鞋,對於這個代碼可能有點不理解,這裏做一個解釋。

  1. template<typename Type, typename... Types> : 這一行中typename... Types定義一個可變類型個數的模板聲明,並且Types被稱爲模板參數包,在這個聲明中:
    • 模板參數個數可變。
    • 模板參數的類型可以不同。
    • 模板參數的個數可以是0個。
  2. void printx(const Type& arg1, const Types&... args) : 在這一行中const Types&... args定義可變類型和個數的參數,args被稱作爲函數參數包,在這個聲明中:
    • 模板參數個數可變。
    • 模板參數的類型可以不同。
    • 模板參數的個數可以是0個。
  3. sizeof...(args) : 這一行中計算參數包中參數的個數。
  4. printx(args...); : 這一行中args...代表整個參數包。

所以從上面的調用可以發現,整個調用過程形成一個遞歸調用,每次調用導致參數包的個數減少一個,並且我們定義了一個void printx()函數爲退出函數(參數包的個數爲0, 代表空參數調用);

2. MyTuple的定義

根據上面模板參數包的轉發,我們可以很容易的定義出一個可變參數的類的模板參數的轉發定義,如下:

template<typename...Values>
class MyTuple;

template<>
class MyTuple<>
{
};

template<typename Head, typename... Tail>
class MyTuple<Head, Tail...> : public MyTuple<Tail...>
{
public:
	Head m_Data;
};
int main(int args, char* argv[])
{
	MyTuple<int, double, char, short> t;
	return 0;
}

整個定義的t結構體如下:
在這裏插入圖片描述

那麼這個類是怎麼定義的呢?整體也可以定義成爲遞歸狀態,如下:
在這裏插入圖片描述

  1. 第一次類類型爲MyTuple<int, double, char, short>, 此時繼承的是MyTuple<double, char, short>.
  2. 第二次類類型爲MyTuple<double, char, short>, 此時繼承的是MyTuple<char, short>.
  3. 第三次類類型爲MyTuple<char, short>, 此時繼承的是MyTuple<short>
  4. 第四次類型爲MyTuple<short>, 此時繼承的是MyTuple<>.
  5. 第五次爲終止類型爲MyTuple<>

對於std::tuple的實現原理其實跟這個也是一樣的,定義如下:

template<class _This,
	class... _Rest>
	class tuple<_This, _Rest...>
		: private tuple<_Rest...>
{	// recursive tuple definition
	_Tuple_val<_This> _Myfirst;	// the stored element
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章