[英]C++ STL container for template base class
我试图在STL映射中存储从模板化基类派生的对象。 但是,尝试插入派生(或实际上是基础)对象将返回:
C2440 'initializing' : cannot convert from 'CBase<T> ' to 'CBase<T>'
我知道使用派生类是使STL容器异构的一种公认方法(http://www.parashift.com/c++-faq-lite/containers.html#faq-34.4)。 我想知道是否可以在这种情况下使用模板。 这将非常方便,因为我可以在基类中对在编译时针对各种类型实例化的一系列容器进行单个声明,而不是在非模板派生类中进行重复声明。
我的代码如下:
//Header
using namespace std;
template<class T>
class CBase
{
public:
CBase::CBase() {};
virtual CBase::~CBase() {};
vector<pair<int, T> > RetrieveVect() { return vect; };
private:
vector<pair<int, T> > vect;
};
class CDerivedString : public CBase<string>
{
...
};
class CDerivedInt : public CBase<int>
{
...
};
//cpp
int main(void)
{
//Map specialised for pointer to base class
map<string, CBase<class T>* > m_myMap;
string s = "key";
//Create and insert object (base class)
CBase<int> *dataInt = new CBase();
//The following results in error C2440: 'initializing' : cannot convert from 'CBase<T> ' to 'CBase<T>
m_myMap.insert(std::make_pair(s, dataInt));
//Create and insert object (derived class)
CBase<int> *dataBase = new CBase<int>();
//The following results in error C2440: 'initializing' : cannot convert from 'CBase<T> ' to 'CBase<T>
m_myMap.insert(pair<string, CBase<class T>* >(s, static_cast<CBase*>(dataInt)));
}
我尝试在派生类指针上进行dynamic_cast,以将其强制转换为基本指针类型,但这也不起作用:
//error C2440: 'static_cast' : cannot convert from 'CBase<T> *' to 'CBase<T> *'
m_myMap.insert(pair<string, CBase<class T>* >(s, static_cast<CBase<class T>*>(dataInt)));
下一行:
map<string, CBase<class T>* > m_myMap;
几乎可以肯定,这并不意味着您认为的那样。 这等效于:
map<string, CBase<T>* > m_myMap;
也就是说:“ T”是一个具体的类,而不是模板参数。 这些类之间当然没有关系:
CBase<int>
和
CBase<T>
因此,错误消息-您从未定义(或打算)具体的类'T'。 使用正确的基数重新获取SCFrench的注释,然后在map <>中使用该注释:
map<string, CBase<int>* > m_myIntMap;
将允许您存储具体的CDerivedInt *对象。 如果要存储任何对象,请定义一个完全通用的基础:
class CBaseAbc
{
virtual ~CBaseAbc() = 0;
};
template<class T>
class CBase : public CBaseAbc
{
// etc.
};
map<string, CBaseAbc* > m_myAnthingMap;
使用Boost的Pointer Containers ,它确实提供了您尝试过的“专用于指向基类的指针的映射”:
// Use whichever is appropriate since you've written CBase as a template:
boost::ptr_map<string, CBase<int> > m_myMap;
boost::ptr_map<string, CBase<string> > m_myMap;
// If CBase were instead not a template base class:
boost::ptr_map<string, CBase> m_myMap;
由于您在CBase的界面中使用了T,因此看来您想将CBase保留为模板,但是请注意,在这种情况下,从CBase <int>和CBase <string>派生的类之间没有通用的基类。两种不同的类型,并且您不能将从这两种类型派生的类存储在单个容器中。
您需要有一个基类来存储在std::map
; 必须是非模板类或模板的特定实例。 除非所有实例都有通用的基类,否则无法存储“ CBase
任何实例”。 您可能还需要考虑使用boost::shared_ptr
或std::shared_ptr
自动管理对象的生存期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.