[英]How I can keep track of all the functions defined with a macro to later call them all at once?
I have the following code to define new functions by using a macro我有以下代码通过使用宏来定义新函数
#include <iostream>
#define CONCAT(x, y) x##y
#define PREFIX_COUNTER(prefix, counter) CONCAT(prefix, counter)
#define FUNC() void PREFIX_COUNTER(func_, __COUNTER__)()
FUNC() {
std::cout << "first func" << std::endl;
}
FUNC() {
std::cout << "second func" << std::endl;
}
int main(int, char **) {
func_0();
func_1();
return 0;
}
Each call to FUNC
will define a new function like func_0
, what I need to do now is to call to all the functions defined by func like this:每次调用FUNC
都会定义一个新的 function ,比如func_0
,我现在需要做的是像这样调用 func 定义的所有函数:
int main(int, char **) {
CALL_ALL_FUNC(); // this will call func_0 and func_1
return 0;
}
Could be possible to append the name of every new FUNC call into something like a vector so later I can iterate it?是否可以将每个新 FUNC 调用的名称 append 转换为向量之类的东西,以便稍后我可以对其进行迭代? Does the preprocessor has something like that?预处理器有类似的东西吗?
Well you can do some horrid things like the code below (just an outline of the idea).好吧,你可以做一些可怕的事情,比如下面的代码(只是一个想法的概述)。 Should you really do it or not is up to you however.但是,您是否真的应该这样做取决于您。
static std::vector<std::function<void()>> g_vec;
class Reg
{
public:
Reg(std::function<void()> f) { g_vec.push_back(f); }
};
// insert __declspec(selectany) for your compiler and do some better function passing around, maybe C style
#define FUN(x) void v##x(); inline static Reg r##x { []{ v##x(); } }; void v##x()
FUN(a)
{
std::cout << "a\n";
}
FUN(b)
{
std::cout << "b\n";
}
int main(int argc, const char * argv[])
{
for (auto& f : g_vec)
f();
}
Since Catch2 was mentioned, here is an example based off of the macros there.由于提到了 Catch2,这里是一个基于那里的宏的示例。
#include <iostream>
#include <vector>
struct Func;
std::vector<Func*> func_group;
struct Func {
Func() {
func_group.push_back(this);
}
virtual void action() = 0;
};
#define CONCAT(x, y) x##y
#define PREFIX_COUNTER(prefix, counter) CONCAT(prefix, counter)
#define UNIQUE_FUNC(id) \
struct PREFIX_COUNTER(Func_, id) : public Func {\
void action();\
} PREFIX_COUNTER(func_instance_, id);\
void PREFIX_COUNTER(Func_, id)::action()
#define FUNC() UNIQUE_FUNC(__COUNTER__)
FUNC() {
std::cout << "first func" << std::endl;
}
FUNC() {
std::cout << "second func" << std::endl;
}
int main() {
for (auto func : func_group)
func->action();
return 0;
}
FUNC
macro.为每个FUNC
宏定义了一个新的派生 class。func->action()
). ( func->action()
)。I'm not entirely sure what you are trying to do here, but I don't think that a macro is the correct approach.我不完全确定你想在这里做什么,但我不认为宏是正确的方法。
__COUNTER__
increments every time it appears, so you can't ever actually check how many functions are defined (as the number will keep incrementing). __COUNTER__
每次出现时都会递增,因此您无法实际检查定义了多少个函数(因为数字会不断递增)。 Likewise, if you (or a library) uses it elsewhere, there isn't any way to tell how many functions were created and how many times __COUNTER__
was incremented by something else.同样,如果您(或库)在其他地方使用它,则没有任何方法可以告诉您创建了多少函数以及__COUNTER__
被其他东西递增了多少次。
A possible alternative solution to your problem is to create an std::vector
of function pointers .您的问题的一个可能的替代解决方案是创建一个std::vector
of function pointers 。 You can also combine this with lambda expressions and wrap it in a singleton or a static class to get somewhat close to what you want to define:您还可以将其与 lambda 表达式结合起来,并将其包装在 singleton 或 static class 中,以接近您想要定义的内容:
//DynamicFunctions.h
#include <vector>
#include <functional>
class DynamicFunctions {
public:
static void add(std::function<void()> const& function) {
_functions.push_back(function);
};
static void call(int index) {
//TODO: range checking
_functions[index]();
}
static void runAll() {
for (auto const& func : _functions) {
func();
}
};
private:
static std::vector<std::function<void()>> _functions;
};
std::vector<std::function<void()>> DynamicFunctions::_functions = std::vector<std::function<void()>>();
//main.cpp
#include <iostream>
#include "DynamicFunctions.h"
int main() {
DynamicFunctions::add([]() { std::cout << "Functions[0]" << std::endl; });
DynamicFunctions::add([]() { std::cout << "Functions[1]" << std::endl; });
DynamicFunctions::add([]() { std::cout << "hi!" << std::endl;});
DynamicFunctions::call(2);
DynamicFunctions::runAll();
return 0;
}
This way, whenever you needed to create a dynamic function, instead of using the macro you would call DynamicFunctions::add
.这样,无论何时您需要创建动态 function,您都可以调用DynamicFunctions::add
而不是使用宏。 To run a function, instead of calling func_0
, you would pass that index to DynamicFunctions::call(0)
.要运行 function,而不是调用func_0
,您可以将该索引传递给DynamicFunctions::call(0)
。 This way, as it's all stored in a std::vector
, you can easily iterate through them when you need to call DynamicFunctions::runAll
这样,因为它全部存储在std::vector
中,所以当您需要调用DynamicFunctions::runAll
时,您可以轻松地遍历它们
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.