C++ 更改模板参数c++;
我使用模板创建了一个动态扩展的容器类。 但这只能存储相同数据类型的对象。 如何创建一个动态扩展的容器类,并在扩展该类时保存指定类型的对象 这是为了例如:- 如果obj是所述类别的对象 我应该可以调用一个函数,比如C++ 更改模板参数c++;,c++,templates,C++,Templates,我使用模板创建了一个动态扩展的容器类。 但这只能存储相同数据类型的对象。 如何创建一个动态扩展的容器类,并在扩展该类时保存指定类型的对象 这是为了例如:- 如果obj是所述类别的对象 我应该可以调用一个函数,比如 obj.foo<int>(25); obj.foo(25); 然后使用相同的函数将第二个成员存储为布尔类型或浮点 obj.foo<bool>(true); obj.foo(真); 有什么方法可以做到这一点吗?我曾经考虑过模板,但是我不能在不知道数据类型的
obj.foo<int>(25);
obj.foo(25);
然后使用相同的函数将第二个成员存储为布尔类型或浮点
obj.foo<bool>(true);
obj.foo(真);
有什么方法可以做到这一点吗?我曾经考虑过模板,但是我不能在不知道数据类型的情况下设置类成员,C++17是一个可以存储任意对象的类,因此您可以简单地使用容器类来存储std::any
对象
这只是一个C++库添加,它并没有真正使用任何核心C++语言的特性,所以在C++ 17之前,可以简单地实现自己的版本
std::shared_ptr
的类型擦除功能,让容器存储std::shared_ptr
对象。插入函数模板可以使用make_shared
为添加到容器中的任何类型构造std::shared_ptr
,然后使用std::static_pointer_cast
将其转换为std::shared_ptr
,然后将其存储在容器中
但是,当然,您必须确定存储在容器中的每个对象的类型,这可能会非常痛苦
如果容器可以存储的所有不同类都是同一基类的所有子类,那么您只需将std::shared_ptr
放入容器中,就可以结束了。这将是更简单的解决方案。这里有一个c++03方法:
#include <vector>
#include <string>
#include <typeinfo>
class Entry{
public:
class Exception_TypeFail : std::exception {
public:
~Exception_TypeFail() throw() {
}
const char* what() const throw(){
return "Failed to cast";
}
};
class PolymorphInterface{
public:
virtual ~PolymorphInterface() {};
virtual bool isType(const std::type_info &testType) const =0;
};
template<typename TYPE>
class Polymorph : public PolymorphInterface{
private:
TYPE mData;
public:
Polymorph(const TYPE ©Me)
: mData(copyMe) {
}
bool isType(const std::type_info &testType) const {
return testType == typeid(mData);
}
TYPE& get(){
return mData;
}
};
Entry(PolymorphInterface *manageMe)
: mManageMe(manageMe) {
}
Entry(const Entry ©Me)
: mManageMe(const_cast<Entry&>(copyMe).mManageMe) {
const_cast<Entry&>(copyMe).mManageMe = NULL;
}
~Entry(){
delete mManageMe;
}
template<typename TYPE>
bool isType(){
return mManageMe->isType(typeid(TYPE));
}
template<typename TYPE>
TYPE& get(){
if(!mManageMe->isType(typeid(TYPE)))
throw Exception_TypeFail();
return dynamic_cast< Polymorph<TYPE>* >(mManageMe)->get();
}
template<typename TYPE>
const TYPE& getConst() const {
if(!mManageMe->isType(typeid(TYPE)))
throw Exception_TypeFail();
return dynamic_cast< Polymorph<TYPE>* >(mManageMe)->get();
}
private:
PolymorphInterface *mManageMe;
};
int main(){
//- I'm using std lib containers the same way your container may work
std::vector<Entry> magicContain;
magicContain.push_back(
Entry(new Entry::Polymorph<int>(42))
);
magicContain.push_back(
Entry(new Entry::Polymorph<float>(1.5f))
);
magicContain.push_back(
Entry(new Entry::Polymorph<std::string>("hi there."))
);
if(magicContain[0].isType<long>())
long iShouldNotBeHere = 0;
std::string impressYourFriends;
if(magicContain[2].isType<std::string>())
impressYourFriends = magicContain[2].get<std::string>();
const std::vector<Entry> frozenMagic( magicContain );
return frozenMagic[0].getConst<int>();
}
#包括
#包括
#包括
班级报名{
公众:
类异常\u TypeFail:std::异常{
公众:
~Exception_TypeFail()throw()异常{
}
常量字符*what()常量抛出(){
返回“未能转换”;
}
};
类多态接口{
公众:
虚拟~PolymorphInterface(){};
虚拟布尔isType(const std::type_info&testType)const=0;
};
模板
类多态:公共多态接口{
私人:
类型mData;
公众:
变形(常量类型和复制)
:mData(copyMe){
}
bool isType(const std::type_info&testType)const{
返回testType==typeid(mData);
}
TYPE&get(){
返回mData;
}
};
条目(多态接口*manageMe)
:mManageMe(manageMe){
}
条目(const条目和copyMe)
:mManageMe(const_cast(copyMe).mManageMe){
const_cast(copyMe).mManageMe=NULL;
}
~Entry(){
删除mManageMe;
}
模板
布尔isType(){
返回mManageMe->isType(typeid(TYPE));
}
模板
TYPE&get(){
如果(!mManageMe->isType(typeid(TYPE)))
抛出异常_TypeFail();
返回动态(mManageMe)->get();
}
模板
常量类型&getConst()常量{
如果(!mManageMe->isType(typeid(TYPE)))
抛出异常_TypeFail();
返回dynamic_cast(mManageMe)->get();
}
私人:
多态接口*mManageMe;
};
int main(){
//-我使用std-lib容器的方式与您的容器的工作方式相同
std::载体magicContain;
魔术师。推回(
条目(新条目::Polymorph(42))
);
魔术师。推回(
条目(新条目::多晶型(1.5f))
);
魔术师。推回(
条目(新条目::Polymorph(“hi there.”)
);
if(magicContain[0].isType())
long iShouldNotBeHere=0;
字符串给你的朋友留下深刻印象;
if(magicContain[2].isType())
impressYourFriends=magicContain[2].get();
常数std::向量冻结魔法(magicContain);
返回frozenMagic[0].getConst();
}
如果到处都有这些调用,则不太可能,因为容器无法事先知道将调用哪个模板参数foo
。您可以求助于void*
或更好的std(c++17)/boost::any
。但是这就破坏了在foo
@GillBates上有一个模板参数的模板理由,所以我没有办法做到??不,没有办法,不在保存的同一个容器对象内。除非使用上面描述的方法。也许像std::any
这样的方法可以帮助您?我正在寻找一个更简单、更容易理解的解决方案,但似乎我有点不知所措……没关系。这是C++最神秘的部分之一。