使用元数据标记 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>();
}
我有一个 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>();
}