【问题标题】:Preprocessor array generation预处理器数组生成
【发布时间】:2012-09-04 10:25:08
【问题描述】:

我正在尝试创建一个宏来替换函数定义。这个宏应该在某个数组中注册函数的名称,以便其他宏可以对数组的元素做一些事情。

我想这样做以获得可以在控制台中使用的函数列表,而无需在添加新函数时编辑列表(实际上是多个列表)。

在阅读了一些内容后,我查看了 boost 预处理器。不幸的是,似乎没有办法“保存”新数组。 我想做的是这样的:

#define SOME_ARRAY (0, ())
#define CONSOLE_COMMAND(a) \
  #redefine SOME_ARRAY BOOST_PP_ARRAY_PUSH_BACK(SOME_ARRAY, #a) \
  void a(some_arguments)

很遗憾,据我所知,redefine 不存在,#define 不能在宏中使用(如果我错了,请纠正我)。

我查看了 boost 的预编译器的 SLOT,但我认为一旦设置,我也无法更改其中的变量。

除了编写我自己的预处理器之外,还有其他方法吗?不是,学习如何写一个好的开始是什么? (将 MinGW 与 Code::Blocks 一起使用)。

【问题讨论】:

  • 我确信有一些易于维护的方法可以在不使用预处理器的情况下解决您的问题。为什么不描述问题?

标签: c++ gcc boost-preprocessor


【解决方案1】:

做类似事情的常用方法是使用特殊宏在头文件中声明函数。这个宏的定义会根据它包含在哪个源文件中而有所不同。通常它只会定义一个标准函数原型,但是当包含在一个特殊的源文件中时,它会被定义为在表中添加条目。

类似这样的:

// functions.h
#ifndef FUNCTION_H_
#define FUNCTION_H_

#ifndef FUNCTION
# define FUNCTION(name) \
    void name(const std::vector<std::string> &);
#endif

FUNCTION(foo)
FUNCTION(bar)

#endif

// functions.cpp
// File that defines the function table

#include <functional>

using function_type = std::function<void(const std::vector<std::string> &)>;

#define FUNCTION(name) \
    { #name, name },

std::map<std::string, function_type> functions = {
#include "functions.h
};

现在你有一个 std::map 包含指向函数的指针,由函数名称索引。

是的,您仍然需要维护一个函数“列表”,即functions.h 中的原型列表,但是当您添加(或删除)函数时,“修改”这个列表非常容易。

【讨论】:

    【解决方案2】:

    预处理器的设计目的不是能够重新定义符号,因此您不能使用它来累积文件传递中的值。

    一种可能的解决方案是使用重新定义和自我重新包含作为 X-Macros 技术:

    #define CONSOLE_COMMAND(a,body) \
        void a(some_arguments) body
    
    CONSOLE_COMMAND(my_command, { ... })
    
    const char *array[] = {
    #undef CONSOLE_COMMAND
    #define CONSOLE_COMMAND(a,body) #a ,
    #include __FILE__
    };
    

    更惯用的 C++ 解决方案是将您的命令作为文件范围对象,其构造函数在程序启动时注册它们。

    【讨论】:

    • 因此,如果我理解正确,它与 Joachim Pileborg 的解决方案的概念相同:更改定义并重新包含在数组中,因此它现在成为所需的条目。我真的不明白 COMMAND_NAME 和 COMMAND_DEFINITION 是干什么用的。
    • @DrBearhands 哎呀,忽略那些。
    猜你喜欢
    • 1970-01-01
    • 2011-07-18
    • 2014-11-27
    • 2018-12-29
    • 1970-01-01
    • 2021-10-28
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多