C++ 更改模板参数c++;

C++ 更改模板参数c++;,c++,templates,C++,Templates,我使用模板创建了一个动态扩展的容器类。 但这只能存储相同数据类型的对象。 如何创建一个动态扩展的容器类,并在扩展该类时保存指定类型的对象 这是为了例如:- 如果obj是所述类别的对象 我应该可以调用一个函数,比如 obj.foo<int>(25); obj.foo(25); 然后使用相同的函数将第二个成员存储为布尔类型或浮点 obj.foo<bool>(true); obj.foo(真); 有什么方法可以做到这一点吗?我曾经考虑过模板,但是我不能在不知道数据类型的

我使用模板创建了一个动态扩展的容器类。 但这只能存储相同数据类型的对象。 如何创建一个动态扩展的容器类,并在扩展该类时保存指定类型的对象

这是为了例如:-

如果obj是所述类别的对象 我应该可以调用一个函数,比如

obj.foo<int>(25);
obj.foo(25);
然后使用相同的函数将第二个成员存储为布尔类型或浮点

obj.foo<bool>(true);
obj.foo(真);
有什么方法可以做到这一点吗?我曾经考虑过模板,但是我不能在不知道数据类型的情况下设置类成员,C++17是一个可以存储任意对象的类,因此您可以简单地使用容器类来存储
std::any
对象

这只是一个C++库添加,它并没有真正使用任何核心C++语言的特性,所以在C++ 17之前,可以简单地实现自己的版本 STD::任何< /COD> < /P> 然而,这是相当多的工作。例如,您需要使用诸如placement new之类的高级语言功能。这不是几段话可以解释的

但是,另一种不费吹灰之力的方法可能是利用
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 &copyMe)
        : 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 &copyMe)
    : 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++最神秘的部分之一。