2012-09-04 79 views
0

我正在嘗試創建一個宏來替換函數定義。這個宏應該在某個數組中註冊該函數的名稱,以便其他一些宏可以對該數組的元素進行操作。預處理器陣列生成

我想這樣做有一個可以在控制檯中使用的函數列表,而不必在添加新函數(實際上是多個列表)時編輯列表。

讀了一下後,我看了一下boost預處理器。不幸的是,似乎沒有辦法'保存'新陣列。 我想要做的是這樣的:

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

不幸的是,據我所知,重新定義不存在,#定義不能在宏中使用(請糾正我,如果我錯誤)。

我看了一下boost的預編譯器的SLOT,但我不認爲我可以在其中設置一個變量。

除了編寫我自己的預處理器之外,有什麼辦法可以做到嗎?不是,在學習如何寫一篇文章的時候會是一個好的開始? (使用MinGW和Code :: Blocks)。

+4

我敢肯定,在不使用預處理器的情況下,可以輕鬆地維護您的問題。你爲什麼不描述這個問題? – jrok

回答

3

做類似事情的一種常見方式是使用特殊的宏在頭文件中聲明函數。這個宏將根據它包含在哪個源文件中而有不同的定義。通常它只定義一個標準函數原型,但是當包含在一個特殊的源文件中時,它將被定義爲在一個表中添加條目。

事情是這樣的:

// 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的原型列表,但是當你添加(或刪除)函數時,很容易「修改」這個列表。

0

預處理器的設計目的不是爲了能夠重新定義符號,所以您不能使用它來在通過文件的過程中累積值。

一種可能的解決辦法是使用一個重新定義和自我重新加入作爲X宏技術:

#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++的解決辦法是有你的命令,文件範圍的對象,其構造寄存器他們在程序啓動時。

+0

因此,如果我理解正確,它與Joachim Pileborg解決方案的概念相同:更改定義並重新包含在數組中,以便它現在成爲所需的條目。雖然我不明白COMMAND_NAME和COMMAND_DEFINITION是什麼。 – DrBearhands

+0

@DrBearhands哎呀,不理那些。 – ecatmur