最近学习了C++2.0版本的一些新的特性,利用Variadic Templates(可变参数模板)实现tuple函数。
语言环境
Dev-C++ 5.11
并需要自己的环境是支持C++11的,例如:Dev-C++ 5.11可以通过以下步骤进行修改:
源码
#include <iostream>
#include <algorithm>
using namespace std;
namespace myTuple {
template <typename... Values> class tuple;
template <> class tuple<> {};
template <typename Head, typename... Tail>
class tuple<Head, Tail...>
: private tuple<Tail...> //注意这里的私有继承
{
typedef tuple<Tail...> inherited;
public:
tuple() {}
tuple(Head v, Tail... vtail)
:m_head(v), inherited(vtail...) {}
Head head() {
return m_head;
}
inherited& tail() {
return *this; //这里涉及派生类到基类的类型转换
}
protected:
Head m_head;
};
}
int main() {
myTuple::tuple<int,float,string> t(41,6.3,"nico");
cout<<t.head()<<endl;
cout<<t.tail().head()<<endl;
cout<<t.tail().tail().head()<<endl;
system("pause");
return 0;
}
原理
- 在调用自己实现的tuple时,也就是
class tuple<Head, Tail...>
,就会分为第一个参数41,和之后的6.3,“nico”; - 在tuple类里面,定义了Head类型就是我们每次传入的第一个参数,剩余的定义了类型别名inherited;
- 在类内,定义了head()以及tail()函数,返回值为2中提到的两个类型,在我们调用这两个函数的时候,就会返回对应的值和指针;
- tuple<Tail…> 会进行继承,直到最后一个参数。
运行结果展示
注意:
- 不要起和标准库中的tuple冲突的名字,或者在自己的命名空间下;
- 要保证编译器支持C++11
- 当前的C++11以及以上已经有tuple函数, 可以直接进行使用。
同理,使用decltype
#include <iostream>
#include <algorithm>
using namespace std;
namespace myTuple {
template <typename... Values> class tuple;
template <> class tuple<> {};
template <typename Head, typename... Tail>
class tuple<Head, Tail...>
: private tuple<Tail...> //注意这里的私有继承
{
typedef tuple<Tail...> inherited;
protected:
Head m_head;
public:
tuple() {}
tuple(Head v, Tail... vtail)
:m_head(v), inherited(vtail...) {}
auto head()->decltype(m_head) {
return m_head;
}
inherited& tail() {
return *this; //这里涉及派生类到基类的类型转换
}
};
}
int main() {
myTuple::tuple<int,float,string> t(41,6.3,"nico");
cout<<t.head()<<endl;
cout<<t.tail().head()<<endl;
cout<<t.tail().tail().head()<<endl;
system("pause");
return 0;
}
运行结果展示
- 这里只是使用decltype推导了一下head()的返回值