关于C++tuple的一种继承实现的扩展,实现方式用的是模板递归私有继承。
我想要用public继承实现多态效果,模板多态只要基类能够推导出派生类的类型,就能实现。
#include"Head.h"
#include<typeinfo>
using namespace std;
class ____ {};//用来控制递归继承的顺序
template<typename ...T>
struct type_list;//用来保存子类的类型信息
template<typename Head, typename ...Tail>
class obj ://start
public obj<____, type_list<Head, Tail...>, Tail...> {
Head m_data;
public:
obj(const Head& data, Tail...args) :
obj<____, type_list<Head, Tail...>, Tail...>
(____{}, type_list<Head, Tail...>{}, args...),
//把自己的类型信息传递给父类构造函数
m_data(data)
{
cout << "obj type is " << typeid(*this).name() << endl;
}
Head& head() { return m_data; }
};
//
template<typename T, typename Head, typename ...Tail>
class obj<____, T, Head, Tail...> :
public obj<____, type_list<Head, Tail...>, Tail...> {
Head m_data;
T Prev;//存储上一个子类的类型信息
//一开始并不想给过程中的子类存储类型信息,但是如果直接将类型信息传到最后,也就失去了多态的能力,因为初始化基类必须知道子类的类型,我需要的就是通过一个基类指针可以实现多态。
public:
using prev_type = typename decltype(Prev)::types;
obj(____ _, const T& t, const Head& data, Tail...args) :
obj<____, type_list<Head, Tail...>, Tail...>
(_, type_list<Head, Tail...>{}, args...),
//这里同上面一样
m_data(data),
Prev(t)
{
cout << "obj type is " << typeid(*this).name() << endl;
cout << typeid(typename decltype(Prev)::types).name() << endl;
}
prev_type& prev() {
prev_type* ptr = this;
return *ptr;
}
Head& head() { return m_data; }
};
template<typename T>
class obj<____, T> {//end
T Prev;
public:
//最终传入的是一个____,和第一个派生类的类型信息,可以只做一点处理就可以做到任意obj对象都派生于一个基类。
using prev_type = typename decltype(Prev)::types;
using baseType = obj<____, T>;
obj(____ _, T t) :Prev(t) {
cout << "obj type is " << typeid(*this).name() << endl;
cout << typeid(prev_type).name() << endl;
}
prev_type& prev() {
prev_type* ptr = this;
return *ptr;
}
};
template<typename ...T>
struct type_list {//为了直观的看到类型信息,其实这个类只需要using types这一行就够了。
using types = obj<____, type_list<T...>, T...>;
string type;
type_list() :type(typeid(types).name()) {
cout << type << endl;
}
type_list(const type_list& a) :type(a.type) {
cout << "copy ctor " << type << endl;
}
};
//做了很多测试,卡了我快一个星期,现在看下最直观的
int main(int argc, char const* argv[])
{
type_list<int, int, int>list;
obj<int, int, int>o(3, 2, 1);
decltype(o)::baseType& base = o;
auto base1 = base.prev();
auto base2 = base1.prev();
return 0;
}