使用元数据

时间:2016-06-23 17:26:58

标签: c++ templates factory-pattern

我有一个C ++工厂函数,它将用于实例化某些抽象类派生的具体类。

从代码操作的角度来看,这些具体类的实际英文名称并不重要。假设它们是不同类型的“事件”,派生自“AbstractEvent”类。出于代码函数的目的,派生类的实际名称无关紧要,因为它们都会在实例化时生成某种唯一的数字ID,这将是其他模块引用它们的方式,这只能用于对抽象类型的引用,而不是任何特定的具体类。

从代码维护的角度来看,对于编码人员来说,知道是否某个类或方法接受一个模板化的“FooEvent”与一个int一起工作或者一个模板化的“BarEvent”与一个浮点数,因此在使用API​​时,用户可以使用一些人类可读的术语。

有没有“规范”的方法来实现这一目标?如果解决方案不会产生任何运行时开销,那将是更可取的。

1 个答案:

答案 0 :(得分:1)

constexpr字符串标识符怎么样:

#include <iostream>
#include <string>
#include <memory>

struct EventBase
{
    virtual const std::string& type() const = 0;
    virtual ~EventBase() = default;
};

template<const char* type_name>
struct EventModel : EventBase
{

    const std::string& type() const override {
        static const std::string _ { type_name };
        return _;
    }
};

constexpr char hello[] = "hello";
constexpr char world[] = "world";

int main(int argc, const char * argv[]) {

    auto p1 = std::make_unique<EventModel<hello>>();
    auto p2 = std::make_unique<EventModel<world>>();

    std::cout << p1->type() << std::endl;
    std::cout << p2->type() << std::endl;
    return 0;
}

现在您有多种选择消息类型的选项:

bool is_hello_slow(const EventBase& e)
{
    return e.type() == hello;
}

bool is_hello_medium(const EventBase* pe)
{
    return dynamic_cast<const EventModel<hello>*>(pe);
}

template<class Event>
bool is_hello_compile_time(const Event&) {
    return std::is_base_of<EventModel<hello>, Event>();
}