现代C ++中是否有一种“扩展”功能的方法? 也许这个伪代码可以解释我想要的东西:
extendable void foo()
{
doSomething();
}
extend foo()
{
moo();
}
编译时,函数foo()
应该这样做:
foo()
{
doSomething();
moo();
}
我以为我可以通过在foo()
中将每个函数存储在函数指针的std :: vector中来实现这一点,foo()
将循环遍历向量并运行所有函数。
但是,我需要在编译时执行此操作,因此无法运行vector.push_back()
。
我试图在#define指令的帮助下做到这一点,但我找不到解决方案。
提前感谢您的回答。
我想实现某种Entity-Component-System,每个组件都有一个列表。每个实体都有一个ID,指向组件列表中的list元素。 因为我不想重复创建新类型组件的步骤,所以我想制作一个#define-directive,以便为我将创建的每个新组件自动生成它。
主要问题是如果创建了新实体,则向每个组件添加一个元素。 这是我想要的代码:
#define addComponent(name) \
struct name; \
private: \
std::vector<name> name ## vector; \
public: \
extend addEntity() \
{ \
struct name a; \
name ## vector.push_back(a); \
} \
void set ## name(const int & ID, name newName) \
{ \
name ## vector[ID] = newName; \
} \
name get ## name(const int & ID) \
{ \
return name ## vector[ID]; \
}
class Component
{
public:
Component();
~Component();
extendable void addEntity(int * ID);
addComponent(position)
struct position
{
float x, y, z;
}
};
答案 0 :(得分:3)
我可以扩展功能吗?
没有
您描述的内容是不可能的。任何机制都不支持编译器生成一个函数,该函数将调用foo()
在扩展之前调用的函数。
虚拟方法不起作用,因为它们提供的只是Polymorphism(希腊语中的许多形式)。
答案 1 :(得分:3)
您没有充分解释您的想法和原因(甚至在编辑后)。对于成员函数,确实阅读了有关vtables的更多信息(实现dynamic dispatch的常用方法)。
请注意,功能可以是值(特别感谢lambda expressions和std::function。)
然后,您可以使用std::dequeue声明函数的双端队列todoque
(它可以是static
变量或某些class
的字段等。 ..)
std::deque<std::function<void(void)>> todoque;
并扩展它,可能使用lambda,
todoque.push_back([](void) { moo(); };
并使用
初始化它 todoque{[](void){doSomething()}};
然后代码
void foo() {
for (auto f : todoque) f();
}
我希望你明白了。
BTW,在上面的示例中,lambda可能不需要,您可能只需编写todoque.push_back(moo)
。
BTW我建议阅读SICP(不是关于C ++,而是关于一种名为Scheme的函数式编程语言),它是一个很好的(并且可以免费下载)编程的介绍。
我以为我可以通过在函数指针的std :: vector中存储我想要的foo()函数来实现这个目的
不,甚至更好,使它成为std::vector<std::function<void(void)>>
并使用lambda表达式。
但是,我需要在编译时这样做,因此我无法运行vector.push_back()
为什么不呢?它可能发生在一些静态数据的构造函数中。
也许你的总体目标(你没有解释)也可能通过涉及JIT compiling的运行时元编程技术和运行时代码的生成来实现。您可以使用libgccjit或LLVM等库;你也可以在一些临时文件中发出C ++代码,将其编译为插件,然后插入dlopen。另见this。
关于您编辑的实体 - 组件 - 系统目标,您是否考虑编写一些适用于构建自动化系统规则的专用C ++代码生成器(或预处理器)(例如make
或ninja
等。 ..)会在构建时明智地触发? Qt moc可能是鼓舞人心的。还可以考虑使用某些通用预处理器,如m4
或gpp。