如何扩展一个函数 [英] How to extend a function

查看:119
本文介绍了如何扩展一个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现代C ++中有没有一种方法可以扩展一个函数?
也许这个伪代码可以解释我想要的:

 可扩展void foo()
{
doSomething();
}

扩展foo()
{
moo();
}

编译函数 foo()应该这样做:

  foo()
{
doSomething();
moo();
}

我想我可以通过存储我想要的每个函数 foo()在函数指针的std :: vector中,并且 foo()将遍历vector并运行所有功能。然而,编译时我需要这样做,因此我不能运行 vector.push_back()



我试图在#define指令的帮助下做到这一点,但我没有找到解决方案。



感谢您提供任何答案。



编辑:我的实际问题



我想实现某种实体 - 包含每个组件的列表的组件系统。每个实体都有一个ID,指向组件列表中的列表元素。
因为我不想重复创建新类型组件的步骤,所以我想创建一个#define-directive来自动创建每个新组件。


如果创建了一个新实体,主要问题是向每个组件向量添加一个元素。
这是我想要工作的代码:

pre $ #define addComponent(name)\
struct名称; \
private:\
std :: vector< name>名称##矢量; \
public:\
extend addEntity()\
{\
struct name a; \
name ## vector.push_back(a); \
} \
void set ## name(const int& ID,name newName)\
{\
name ## vector [ID] = newName ; \
} \
name name ## name(const int& ID)\
{\
return name ## vector [ID]; \
}

类组件
{
public:
Component();
〜Component();

可扩展void addEntity(int * ID);

addComponent(position)
结构位置
{
float x,y,z;
}
};


解决方案

您没有足够解释您的想法以及为什么(甚至在您编辑之后 )。对于成员函数,确实阅读了更多关于 vtables (实现 dynamic dispatch )。



注意,函数可以是值(感谢 lambda表达式 std :: function 显着)。



你然后可以使用 todoque =nofollow noreferrer> std :: dequeue (它可能是一个 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();
}

我希望你有这个想法。

顺便说一句,在上面的例子中,lambda可能不需要,您可能只需编码 todoque.push_back(moo)



顺便说一句,我建议阅读 SICP (不是关于C ++,而是关于一种称为Scheme的函数式编程语言),它是一个优秀的(可自由下载的)编程入门。


我认为我可以通过将foo()中想要的每个函数都存储在函数的std :: vector中指针


不,甚至更好,使它成为 std :: vector< std :: function< void (void)>>< / code>并使用lambda表达式。


然而,我需要在编译时做到这一点,因此我无法运行vector.push_back()

为什么不呢?它可能发生在一些静态数据的构造函数中。



也许你的总体目标(你没有解释)也可以通过运行时元编程技术来实现, JIT编译和在运行时生成代码。你可以使用像 libgccjit LLVM ;您也可以在某个临时文件中发布C ++代码,将其编译为插件,然后 dlopen 该插件。另请参阅

关于您编辑的实体组件系统目标,您是否考虑编写一些专门的C ++代码生成器(或预处理器),以便构建自动化系统的适当规则(例如 make ninja 等等)会在构建时明智地触发? Qt moc 可以鼓舞人心。请考虑使用一些通用的预处理程序,如 m4 gpp


is there a way in modern C++ to "extend" a function? Maybe this pseudo code can explain what I want:

extendable void foo()
{
   doSomething();
}

extend foo()
{
   moo();
}

when compiled the function foo() should do this:

foo()
{
    doSomething();
    moo();
}

I thought I could do this by storing every function that I want to have in foo() in a std::vector of function pointers and foo() will loop through the vector and run all functions.

However, I need to do this while compiling, thus I can't run vector.push_back().

I tried to do this with help of #define directives but I didn't find a solution.

Thanks in advance for any answer.

EDIT: My actual problem

I want to implement some kind of Entity-Component-System with a list for every component. Every entity has an ID that points to the list element in the component-list. Because I don't want to repeat the steps for creating a new type of component I wanted to make a #define-directive to make this automatically for every new component I'll create.

The main problem is to add to every component-vector one element if a new entity is created. This is the code I wanted to work:

#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;
    }
};

解决方案

You don't explain enough what you have in mind and why (even after your edit). For member functions, indeed read more about vtables (a common way to implement dynamic dispatch).

Notice however that functions can be values (thanks to lambda expressions and std::function notably).

You might then declare for example a double ended queue todoque of functions using std::dequeue (it could be a static variable or a field of some class, etc...)

 std::deque<std::function<void(void)>> todoque;

and extend it, perhaps using a lambda,

 todoque.push_back([](void) { moo(); };

and initialize it with

  todoque{[](void){doSomething()}};

then code

 void foo() {
   for (auto f : todoque) f();
 }

I hope you got the idea.

BTW, in the example above the lambda are perhaps unneeded, you might just code todoque.push_back(moo).

BTW I recommend reading SICP (not about C++, but about a functional programming language called Scheme), it is an excellent (and freely downloadable) introduction to programming.

I thought I could do this by storing every function that I want to have in foo() in a std::vector of function pointers

No, or even better, make it a std::vector<std::function<void(void)>> and use lambda expressions.

However, I need to do this while compiling, thus I can't run vector.push_back()

Why not? It might happen in a constructor of some static data.

Maybe your overall goal (which you don't explain) might be also achieved by run-time metaprogramming techniques involving JIT compiling and generation of code at runtime. You could use libraries like libgccjit or LLVM; you could also emit C++ code in some temporary file, compile it as a plugin, and dlopen that plugin. See also this.

Regarding your edited Entity-Component-System goal, did you consider writing some specialized C++ code generator (or preprocessor) that appropriate rules of your build automation system (e.g. make or ninja, etc...) would trigger wisely at build time? The Qt moc could be inspirational. Consider also using some general purpose preprocessor like m4 or gpp.

这篇关于如何扩展一个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆