使用元数据标记 C++ class 个实例

Tagging C++ class instances with metadata

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

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

不过,从代码维护的角度来看,编码人员知道某个 class 或方法是否接受了一个 "FooEvent" 模板以使用 int,或者一个"BarEvent" 被模板化以使用浮点数,因此在使用 API 时,有一些人类可读的术语来表示用户正在使用的内容。

有没有 "canonical" 方法来完成这个?如果解决方案不产生任何 运行 时间的开销,那将是更可取的。

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>();
}