C++能否类型回传,或者能否根据typeid获取到的类型名,反过来再推导类型

Italink 2019-05-28 03:41:08
情况是这样的,我最近看到了C++17的any类(可以存储任何数据类型),但调用对象的_Case()的时候却仍然需要模板参数<>来确定类型,明明在构造的时候就已经确定好类型了,后面却还需要,本来any的作用应该是很强大的,但就因为这一点,它的作用大大折扣了,所以翻了一下源码,也参考了别人的写法,做了一个简单的实现看能否解决这个问题。

有没有人知道"类型回传"的方法
另外附上简易模拟的代码

存储:定义一个基类Base,再派生一个模板类Data,对二者再进行一次封装,构造一个Any类,使用Any类的模板构造函数来构造一个Data对象,这样就能存储任何数据类型。
取值:只能存,但还无法把元素取出,所以Any必须有一个基类Base指针的成员变量,存储构造好的Data对象,使用模板函数_Cast(),利用其模板参数Type,进行一个再将Base类强制转换为Data<Type> 对象。
基本上是这个原理吧。


#include<iostream>
#include<typeindex>
using namespace std;
class Any{
public:
template<typename T>
Any(T t) :myBase(new Data<T>(t)) { }
template<typename T>
T get() {
return dynamic_cast<Data<T>*>(myBase.get())->value;;
}
private:
class Base {
public:
virtual ~Base() {}
};
template <typename T>
class Data :public Base {
public:
typedef T value_type; //传不出去。
Data(T t) {
value = t;
}
T value;
};
unique_ptr<Base> myBase;
type_index index(void); //我想能否根据构造Data类的时候通过修改此变量,可以将函数类型传回来,但是无法用做类型名(!auto,!decltyoe),求告知方法=.=
};
int main() {
Any a(string("s123")), b = 1, c = 12.0;
cout << a.get<string>() << endl; /*调用get函数必须要填写模板参数,我感觉这样大大降低了any的作用*/
cout << b.get<int>() << endl; /*我想能否在构造的时候就确认参数的类型,保证get调用的时候不需要使用模板参数*/
cout << c.get<double>();
return 0;
}

...全文
355 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
636f6c696e 2019-05-29
  • 打赏
  • 举报
回复
我感觉C/C++的可以转换类型的特点就决定了无法获取类型,强类型语言貌似都有获取类型的方法
Italink 2019-05-29
  • 打赏
  • 举报
回复
引用 10 楼 zjq9931 的回复:
需要先存起来。
不好意思啊,不是需要类型名,我是想通过模板构造函数去除模板函数的参数
  • 打赏
  • 举报
回复
这样的类型

#include <iostream>
#include <typeinfo>
using namespace std;

class ClsA
{
public:
	ClsA(){_length=1;_hieght=1;}
	ClsA(int len, int high)
		:_length(len),_hieght(high)	{}
	//virtual void who_am_i()const{ cout <<typeid(this).name() << " in " << "ClsA"<< "\r\n"<<_length <<", " << _hieght <<endl;}
	int _length;
	int _hieght;
};

class ClsB:public ClsA
{
public:
	ClsB(){_length=1;_hieght=1; _width=1;}
	ClsB(int len, int high, int width)
		:ClsA(len,high),_width(width){}
	//virtual void who_am_i()const{ cout <<typeid(this).name() << " in " << "ClsB" << "\r\n" << _length << ", " << _hieght << ", " << _width << endl;}
	int _width;
};

class ClsC:public ClsA
{

};

int main()
{
	ClsA clsA;
	ClsB clsB(1,2,3);
	ClsC clsC;
	int a;

	//clsA.who_am_i();
	//clsB.who_am_i();
	clsA = clsB;	
	//clsA.who_am_i();

	ClsA *pA;
	pA = &clsB;
	//pA->who_am_i();

	cout <<"pA类型" <<typeid(*pA).name() << endl;
	return 0;
}
  • 打赏
  • 举报
回复
需要先存起来。
  • 打赏
  • 举报
回复
typeid运行时类型鉴定的例子:

#include <iostream>
#include <typeinfo>
using namespace std;

class ClsA
{
public:
	ClsA(){_length=1;_hieght=1;}
	ClsA(int len, int high)
		:_length(len),_hieght(high)	{}
	virtual void who_am_i()const{ cout <<typeid(this).name() << " in " << "ClsA"<< "\r\n"<<_length <<", " << _hieght <<endl;}
	int _length;
	int _hieght;
};

class ClsB:public ClsA
{
public:
	ClsB(){_length=1;_hieght=1; _width=1;}
	ClsB(int len, int high, int width)
		:ClsA(len,high),_width(width){}
	virtual void who_am_i()const{ cout <<typeid(this).name() << " in " << "ClsB" << "\r\n" << _length << ", " << _hieght << ", " << _width << endl;}
	int _width;
};

int main()
{
	ClsA clsA;
	ClsB clsB(1,2,3);

	clsA.who_am_i();
	clsB.who_am_i();
	clsA = clsB;	
	clsA.who_am_i();

	ClsA *pA;
	pA = &clsB;
	pA->who_am_i();

	cout <<"pA类型" <<typeid(*pA).name() << endl;
	return 0;
}
  • 打赏
  • 举报
回复
if (xxx.type() == typeid(int))
  • 打赏
  • 举报
回复
std::any::type
Italink 2019-05-29
  • 打赏
  • 举报
回复
引用 3 楼 636f6c696e的回复:
我感觉C/C++的可以转换类型的特点就决定了无法获取类型,强类型语言貌似都有获取类型的方法
还真是,我一层层的翻type的调用,还是不能发现什么方法可以做到,放弃了
Italink 2019-05-29
  • 打赏
  • 举报
回复
引用 4 楼 sdghchj的回复:
放弃吧,C++是静态强类型语言,又没有类型反射机制。 Any类本身不带模板,又能存放任何类型,显然内部是一个通用指针,自然其读写成员函数都需要确定的模板类型参数。
放弃了,谢谢哈
sdghchj 2019-05-29
  • 打赏
  • 举报
回复
放弃吧,C++是静态强类型语言,又没有类型反射机制。 Any类本身不带模板,又能存放任何类型,显然内部是一个通用指针,自然其读写成员函数都需要确定的模板类型参数。
Italink 2019-05-28
  • 打赏
  • 举报
回复
手动置顶=.=,再没人我就放弃了
Italink 2019-05-28
  • 打赏
  • 举报
回复
比较蛋疼的是any类都提供了一个type方法可以得到一个type_info对象,却仍然还需要确定数据类型

65,186

社区成员

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

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