实现可变参数模板类Tuple
参考资料:【C++】C++11可变参数模板(函数模板、类模板)
可变参数模板类机制
C++11极大的增强了模板的功能,支持了可变参数模板类,允许定义包含0到任意个模板参数,其类似于函数的可变参数机制。
C++11的tuple类
C++11中引入了tuple类,其功能类似于Python中的元组,能够存放任意类型和个数的元素。这里给出cplusplus.com的示例代码以简单介绍该类的使用方法。
代码示例
// tuple example
#include <iostream> // std::cout
#include <tuple> // std::tuple, std::get, std::tie, std::ignore
int main ()
{
std::tuple<int,char> foo (10,'x');
auto bar = std::make_tuple ("test", 3.1, 14, 'y');
std::get<2>(bar) = 100; // access element
int myint; char mychar;
std::tie (myint, mychar) = foo; // unpack elements
std::tie (std::ignore, std::ignore, myint, mychar) = bar; // unpack (with ignore)
mychar = std::get<3>(bar);
std::get<0>(foo) = std::get<2>(bar);
std::get<1>(foo) = mychar;
std::cout << "foo contains: ";
std::cout << std::get<0>(foo) << ' ';
std::cout << std::get<1>(foo) << '\n';
return 0;
}
运行结果:
foo contains: 100 y
C++实现Tuple
tuple的实现便是基于可变参数模板类机制,这里我们使用这一机制实现一个自己的Tuple类,具体的方式有两种:继承方式和组合方式。
继承方式实现
继承方式是通过递归继承的方式来构建可变参数模板类的,我们需要定义一个可变参数模板类,再定义一个空包模板类,然后再定义递归展开的模板类,以此来实现可变参数模板类,具体如下所示:
代码测试
继承方式实现Tuple类:
#include<bits/stdc++.h>
using namespace std;
//定义一个可变参数模板类
template<typename... Types>
class Tuple;
//定义一个空参数的模板类,
template<>
class Tuple<>{
public:
friend ostream& operator<<(ostream& out, Tuple<> T){//作为递归最下层的输出,也需要实现该操作符
return out;
}
};
//递归展开 Tuple 中的元素
template<typename TypeZero,typename... Types>
class Tuple<TypeZero,Types...>:private Tuple<Types...>{
typedef Tuple<Types...> inherited; //给继承的类起一个别名
protected:
TypeZero head_v;
public:
Tuple(){}
Tuple(TypeZero v,Types... values):head_v(v),inherited(values...){}
TypeZero& head(){return head_v;} //获取元组的第一个元素
inherited& tail(){return *this;} //获取元组除了第一个元素之外的元素,基类元素和派生类的其实地址是一样的,基类的引用或者指针可以指向派生类
friend ostream& operator<<(ostream& os,Tuple& t){ //友元函数输出整个tuple,需要在空元组中定义该运算符重载函数
os<<t.head()<< " "<<t.tail();
return os;
}
};
int main(){
Tuple<int,double,string,string> t(1,2.0,"hello", "world");
cout<<t<<endl;
return 0;
}
执行结果:
1 2 hello world
组合方式实现
组合方式是将可变参数模板类作为一个成员变量来构建的,这样一层一层的叠加最终形成一个可变参数模板类,具体代码如下所示:
代码测试
#include<bits/stdc++.h>
using namespace std;
//定义一个可变参数模板类
template<typename... Types>
class Tuple;
//定义一个空参数的模板类,
template<>
class Tuple<>{
public:
friend ostream& operator<<(ostream& out, Tuple<> T){//作为递归最下层的输出,也需要实现该操作符
return out;
}
};
//递归展开 Tuple 中的元素
template<typename TypeZero,typename... Types>
class Tuple<TypeZero,Types...>{
typedef Tuple<Types...> composited; //给继承的类起一个别名
protected:
composited composited_m;
TypeZero head_v;
public:
Tuple(){}
Tuple(TypeZero v,Types... values):head_v(v),composited_m(values...){}
TypeZero& head(){return head_v;} //获取元组的第一个元素
composited& tail(){return composited_m;} //获取元组除了第一个元素之外的元素
friend ostream& operator<<(ostream& os,Tuple& t){ //友元函数输出整个tuple,需要在空元组中定义该运算符重载函数
os<<t.head()<< " "<<t.tail();
return os;
}
};
int main(){
Tuple<int,double,string,string> t(1,2.0,"hello", "world");
cout<<t<<endl;
return 0;
}
执行结果:
1 2 hello world
Comments | NOTHING