我可能完全偏离此基础,但我来自c#所以我提前道歉。
首先,关于我想要做的事情。我在我的代码中定义了一个工厂基类
template<typename _Ty>
class Factory
{
public:
virtual std::shared_ptr<_Ty> Create() = 0;
};
我想要做的是有一个工厂列表(比如一个stl向量或列表),然后能够按模板类型搜索它们。到目前为止,我已经发现我需要一个包含某种类型的矢量或列表,所以我想出了:
class FactoryContainer
{
struct FactoryConcept {
virtual ~FactoryConcept() {}
};
template< typename _Ty > struct FactoryModel : FactoryConcept {
FactoryModel( const _Ty& t ) : factory( t ) {}
virtual ~FactoryModel() {}
private:
_Ty factory;
};
std::shared_ptr<FactoryConcept> factory;
public:
template< typename _Ty > FactoryContainer( const _Ty& _factory ) :
factory( new FactoryModel<_Ty>( _factory ) ) {}
};
我想在容器中加入某种方法来比较类型,这是
的内容。template<typename _Ty> bool isType(){...}
但是我没有想法如何实现它,或者我甚至在使用类型擦除后确定类型的正确轨道上。
编辑: 在多次评论这是一个XY问题后,我决定重新强调我正在做的事情(我说过了)。
我希望有一个类型为Factory的stl容器(包括任何和所有实例化的模板类型),并且能够从模板类型中选择一个。对我来说,我看到这样做的最佳方式(可能不是最好的方式)是使用类型封装容器类,并让它能够响应包含的类型实际上是使用提供的模板类型。如果不是,那就放弃吧。我无法按照建议使用dynamic_cast,因为当我试图解决它时,我没有指向任何一种类型的指针。我现在正在研究typeid,希望它能解决我的问题,但我还在等待另一个可能的答案。
编辑2: 在玩了几个答案之后,我发现没有任何东西符合我的要求。简而言之,这就是要求:
基类模板:
template<typename FactoryType>
class Factory
{
public:
virtual std::shared_ptr<FactoryType> Create() = 0;
virtual ~Factory(){}
};
工厂经理班:
class Manager
{
static std::shared_ptr<Manager> singleton;
public:
static std::shared_ptr<Manager> getInstance()
{
if (!singleton) singleton = shared_ptr<Manager>(new Manager);
return singleton;
}
template<typename FactoryType>
Factory<FactoryType>& getFactory()
{
//Pick a factory here by the type and return it by reference
//life cycle is handled by the manager
}
};
管理器将通过核心可执行文件和各种dll来了解。在编译管理器时,将不知道工厂的可能类型,并且它由彼此不了解的代码引用。有可能并且很可能在这里装载了我不知道并且不知道的工厂,因为许多工厂都是由其他人制造并放入dll。
答案 0 :(得分:4)
好吧,既然您正在使用C ++ 11,那么您可以存储std::type_index
个对象。
您使用typeid
运算符检索它们:typeid
返回const std::type_info&
,但type_info
不适合使用,例如。作为地图的关键。所以你为此目的构造了一个std::type_index
对象。实际的解决方案取决于您。
像
这样的东西std::map<std::type_index, std::shared_ptr<factory>>
例如(用您设计的正确指针类型替换shared_ptr
)。
请注意,在C ++中,您会尽量避免运行时类型信息。如果你揭露了你想要实现的目标,我们可以尝试找到更好的解决方案。
提供了比较std::type_info
个对象以实现跨越DLL边界的相等工作(因为这是一个要求,参见您的注释),您可以像这样实现它:
class FactoryContainer
{
struct FactoryConcept {
virtual ~FactoryConcept() {}
virtual const std::type_info& Type() const;
};
template< typename _Ty > struct FactoryModel : FactoryConcept {
FactoryModel( const _Ty& t ) : factory( t ) {}
virtual ~FactoryModel() {}
private:
_Ty factory;
const std::type_info& Type() const { return typeid(_Ty); }
};
std::shared_ptr<FactoryConcept> factory;
public:
template< typename _Ty > FactoryContainer( const _Ty& _factory ) :
factory( new FactoryModel<_Ty>( _factory ) ) {}
template <typename T>
bool hasType() const { return factory->Type() == typeid(T); }
};
用法:
bool result = container.hasType<double>();
答案 1 :(得分:0)
那已经存在。它被称为dynamic_cast<T*>(ptr)
,如果ptr
指向T
或从T
派生的任何类,则返回true,假设{em> static 类型为{{ 1}}和*ptr
都至少有一个虚函数。
您还可以使用T
及相关朋友在运行时发现有关类型的信息。