用于调用一系列具有相似名称的宏生成函数的宏(即 f_0、f_1、f_2、...)

Macro for calling a series of macro-generated functions with similar names (i.e. f_0, f_1, f_2, ...)

我遇到了一个很奇怪的问题,我现在不知道如何解决它。

我正在使用以下宏块生成名称相似的函数:

#define CONCAT_IMPLEMENTATION(arg1, arg2) arg1 ## arg2
#define CONCAT(arg1, arg2) CONCAT_IMPLEMENTATION(arg1, arg2)

#define UNIQUE_FUNCTION_NAME(index) CONCAT(f_, index)

#define GENERATE_FUNCTION() void UNIQUE_FUNCTION_NAME(__COUNTER__) ()

所以代码如下:

GENERATE_FUNCTION()
{
    std::cout << "first function" << std::endl;
}

GENERATE_FUNCTION()
{
    std::cout << "second function" << std::endl;
}

替换为:

void f_0 ()
{
    std::cout << "first function" << std::endl;
}

void f_1 ()
{
    std::cout << "second function" << std::endl;
}

有什么方法可以实现调用所有生成函数的宏或函数吗? 也就是说它会调用从f_0f_N的函数,其中N__COUNTER__ 宏的当前值。
类似的东西:

#define RUN_ALL_GENERATED_FUNCTIONS() // ??? //

int main()
{
    RUN_ALL_GENERATED_FUNCTIONS();
    return 0;
}

在我看来是不可能的。你能给我一些建议吗?

这里不需要宏,只需将函数指针放入向量中,然后您就可以遍历向量依次调用每个函数。一种可能的实现方式是:

#include <vector>
#include <functional>
#include <iostream>

struct Functions
{
    static std::vector<std::function<void()>> functions;

    template <typename T>
    static T make_function(T f)
    {
        functions.push_back(f);
        return f;
    }

    static void call()
    {
        for (auto& f : functions)
        {
            f();
        }
    }
};
std::vector<std::function<void()>> Functions::functions;

auto f_1 = Functions::make_function([]
{
    std::cout << "first function" << std::endl;
});

auto f_2 = Functions::make_function([]
{
    std::cout << "second function" << std::endl;
});

int main()
{
    f_1();
    f_2();
    Functions::call();
}

如果您确实需要,您仍然可以将 Functions::make_function 包装到一个宏中。

预处理器没有魔法。要重载,无论如何你必须枚举所有可能的情况。

#define RUN_ALL_GENERATED_FUNCTIONS_1()  UNIQUE_FUNCTION_NAME(0)();
#define RUN_ALL_GENERATED_FUNCTIONS_2()  RUN_ALL_GENERATED_FUNCTIONS_1()UNIQUE_FUNCTION_NAME(1)();
#define RUN_ALL_GENERATED_FUNCTIONS_3()  RUN_ALL_GENERATED_FUNCTIONS_2()UNIQUE_FUNCTION_NAME(2)();
#define RUN_ALL_GENERATED_FUNCTIONS_4()  RUN_ALL_GENERATED_FUNCTIONS_3()UNIQUE_FUNCTION_NAME(3)();
#define RUN_ALL_GENERATED_FUNCTIONS()  do{ CONCAT(RUN_ALL_GENERATED_FUNCTIONS_, __COUNTER__)() }while(0)

int main() {
    RUN_ALL_GENERATED_FUNCTIONS();
   //  do{ f_0();f_1(); }while(0);
}

请注意 __COUNTER__ 是 non-portable,您不妨使用描述性函数名称(代码的可读性很重要,__func__ 将扩展为有意义的东西)并放置指针使用 __attribute__ 将这些函数添加到自定义链接器部分,然后迭代该部分以执行所有函数。这是典型的做法 - 在测试框架和内核中,使用 .init.fini 等部分。