0

関数定義を置き換えるマクロを作成しようとしています。このマクロは、関数の名前を配列に登録して、他のマクロが配列の要素で何かを実行できるようにする必要があります。

新しい関数を追加するたびにリストを編集することなく、コンソールで使用できる関数のリストを作成したいと思います (実際には複数のリストです)。

少し読んだ後、ブーストプリプロセッサを調べました。残念ながら、新しい配列を「保存」する方法はないようです。私がやりたいことは次のようなものです:

#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 はマクロでは使用できません (間違っていたら訂正してください)。

ブーストのプリコンパイラのSLOTを見てみましたが、一度設定した変数も変更できないと思います。

独自のプリプロセッサを作成する以外にこれを行う方法はありますか? そうではありませんか?(Code::Blocks で MinGW を使用する)。

4

2 に答える 2

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を追加 (または削除) するときに、このリストを「変更」するのは非常に簡単です。

于 2012-09-04T10:47:55.480 に答える
0

プリプロセッサは、シンボルを再定義できるように設計されていないため、ファイルのパスで値を蓄積するために使用することはできません。

考えられる解決策の 1 つは、再定義と自己再インクルードを 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++ ソリューションは、コンストラクターがプログラムの起動時にコマンドを登録するファイル スコープ オブジェクトとしてコマンドを使用することです。

于 2012-09-04T10:43:33.990 に答える