纯C++ variant数据类型

cadinfo 2016-03-19 05:12:51
请对C++模板编程精通的朋友帮忙看看下面的代码,目前VC2010下编译通过,Gcc编译失败
请高人帮忙调试解决,使之能够在两个环境下用到这种数据类型。



// 以下代码 Christopher Diggins于2005年1月首次发布
//采用嵌套模板的方法在C++语言中实现了一个变量可以定制承载多种类型的类。
//这个作用和MFC中的VARIANT类似,但更为精炼,且是C++语言级别,因此理论上支持跨平台使用。
//由于近期有这方面的需求,对此做了整理并写了测试代码。
//cq:revised 2016-03-19

//union_list.h开始
struct ul_end {
const int TypeIndex() { return 0; }
};

template<typename Head_T, typename Tail_T, int N>
struct TypeList {
typedef typename TypeList<
typename Tail_T::H_T,
typename Tail_T::T_T,
N - 1>::type
type;
};

template<typename Head_T, typename Tail_T>
struct TypeList<Head_T, Tail_T, 0> {
typedef typename Head_T type;
};

template<typename Head_T, typename Tail_T>
struct ul {
typedef typename ul<Head_T, Tail_T> self;

template<typename T>
ul(T x) : tail(x), tag(false) { }

template<>
ul(Head_T x) : head(x), tag(true) { }

ul(const self& x) : head(x.head), tail(x.tail), tag(x.tag) { }

ul() { };

typedef typename Head_T H_T;
typedef typename Tail_T T_T;

Head_T head;
Tail_T tail;
bool tag;

template<int N>
typename TypeList<Head_T, Tail_T, N>::type& Get()
{
if (N != TypeIndex()) {
throw 0;
}
return *(TypeList<Head_T, Tail_T, N>::type*)InternalGet<N>();
};

template<int N>
void* InternalGet()
{
return tail.InternalGet<N-1>();
};

template<>
void* InternalGet<0>()
{
return &head;
};

const int TypeIndex()
{
return tag ? 0 : tail.TypeIndex() + 1;
}
};
//union_list.h结尾

//test.cpp 开始
/************************************************************************/
/* 使用样例代码 优点是不需要C++11,VC2010通过/GCC不通过 */

#include "union_list.h" //测试一个变量容纳多种数据类型
#include <string>
#include <iostream>
using namespace std;

typedef ul<int,ul<char,ul<bool,ul<double,ul<string,ul<const char*,ul_end>>>>>> test_type;
void output(test_type x)
{
switch(x.TypeIndex()) {
case 0 : cout << "int : " << x.Get<0>() << endl; break;
case 1 : cout << "char : " << x.Get<1>() << endl; break;
case 2 : cout << "bool : " << x.Get<2>() << endl; break;
case 3 : cout << "float : " << x.Get<3>() << endl; break;
case 4 : cout << "string : " << x.Get<4>() << endl; break;
case 5 : cout << "const char* : " << x.Get<5>() << endl; break;
}
}

void main () {
//测试类型
test_type v1=4345;
output(v1);
test_type v2="china";
output(v2);
output('a');
output(3.141);
output(42);
output(string("Hello world"));
output(true);
}
//test.cpp结尾

...全文
392 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
cadinfo 2016-03-20
  • 打赏
  • 举报
回复
引用 6 楼 D41D8CD98F 的回复:
这除了构造函数之外,根本就是一个 tuple 嘛……
我对C++11以后的知识不了解,谢谢提示,我去baidu学习下
D41D8CD98F 2016-03-20
  • 打赏
  • 举报
回复
这除了构造函数之外,根本就是一个 tuple 嘛……
cadinfo 2016-03-19
  • 打赏
  • 举报
回复
引用 3 楼 super_admi 的回复:
恐怕改为GCC的代码比较麻烦,因为GCC和VC关于模板方面的编程规则差异很大。据说,最起码,GCC就不支持类成员函数模板特化……
是不是这个头文件用到了一些GCC不支持的特性? 请教下GCC下有没有类似的,C++语言级别的 类型容器, 就是相同类型变量既可以等于int,也可以等于double,也可以等于const char*等等 在使用时还可以反解的,谢谢!
super_admi 2016-03-19
  • 打赏
  • 举报
回复
恐怕改为GCC的代码比较麻烦,因为GCC和VC关于模板方面的编程规则差异很大。据说,最起码,GCC就不支持类成员函数模板特化……
cadinfo 2016-03-19
  • 打赏
  • 举报
回复
引用 1 楼 yshuise 的回复:
你这个代码可读性太差了! loki库就有这个 还有boost的mpl也有你这个
这个可读性可能是不太好,但这个不需要C++11特性,原作者写于2005年的,应该还是比较有水平的。 我是一个小程序,不想用大库 这份代码在VC2010下运行完美,感兴趣的话你也可以试试看 因为我对模板编程不是很了解,我没有能力修改成支持gcc的版本,所以恳请高人出手,谢谢!
yshuise 2016-03-19
  • 打赏
  • 举报
回复
你这个代码可读性太差了! loki库就有这个 还有boost的mpl也有你这个

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧