C++ 类型删除/类型封装?发现型

标签 c++ templates type-erasure

我可能完全没有根据,但我来自 c#,所以我提前道歉。

首先,简单介绍一下我正在尝试做的事情。我的代码中定义了一个工厂基类

template<typename _Ty>
class Factory
{
public:
    virtual std::shared_ptr<_Ty> Create() = 0;
};

然后我想做的是拥有一个工厂列表(例如 STL vector 或列表),然后能够通过模板类型搜索它们。到目前为止,我已经发现我需要一个 vector 或某种包含类型的列表,所以我想出了:

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 所识别。在编译 Manager 时,工厂的可能类型是未知的,并且由彼此不了解的代码引用。很可能,这里加载了我不知道也不会知道的工厂,因为其中许多工厂是由其他人制作并放入 dll 中的。

最佳答案

好吧,由于您使用的是 C++11,因此您可以存储 std::type_index对象。

您可以使用 typeid 运算符检索它们:typeid 返回一个 const std::type_info&,但 type_info不适合使用,例如。作为 map 的键。因此,您为此目的构造了一个 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>();

关于C++ 类型删除/类型封装?发现型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9486622/

相关文章:

c++ - 将结构体成员函数指针赋值给类函数

c++ - 使用rapidjson c++保存/加载对象 vector

c++ - 如何在 for 循环中记录输入?

templates - 如何在 Symfony2/Twig 模板中包含原始 HTML 文件?

java - 我可以更改 Handlebars.java 中的默认转义吗?

java - 对象化,Key<T> 可能吗?解决方法?

c++ - 零MQ/ZMQPP : Forward metadata with message

C++ 数组包装器

Scala 的 "clean up"类型删除

java - 为什么以下类型在 Java 中是可具体化和不可具体化的?