C ++には、その言語でのコードの自動コンパイルまたは実行時の反映はありません。多くのライブラリフレームワークには、ライブラリ内のシンボルの実行時の反映があります。
したがって、解決策1:問題を独自のダイナミックライブラリに貼り付け、メインプログラムに動的にロードさせ、エクスポートするシンボル名を検索させます。
解決策2:生のCスタイルの関数を名前付きオブジェクトに置き換えます。だからあなたは持っているかもしれません:
class Problem;
void RegisterProblem( std::string name, Problem const* problem );
std::map< std::string, Problem const* >& GetProblems();
class Problem
{
protected:
Problem( std::string name ): RegisterProblem( std::move(name), this ) {}
virtual void operator() const = 0;
virtual ~Problem() {}
};
class Problem1: public Problem
{
public:
Problem1():Problem("Problem1") {}
virtual void operator() const { /* implementation */ }
};
// in .cpp file:
Problem1 problem1Instance();
void RegisterProblem( std::string name, Problem const* problem )
{
GetProblems()[name] = problem;
}
std::map< std::string, Problem const* >& GetProblems()
{
static std::map< std::string, Problem const* > problemMap;
return problemMap;
}
int main()
{
// parse user input to get this string:
std::string testInput = "Problem1";
// run the problem determined by testInput:
Problem* prob = GetProblems()[testInput];
Assert(prob);
(*prob)();
}
上記には、自己登録の問題(静的マップに登録する)と、文字列で指定された問題を実行するmain()が含まれる、ひどく書かれたコードがいくつかあります。
私がよりクリーンになると思う方法は次のとおりです。
// In RegisterProblem.h:
// these two have obvious implementations:
std::map< std::string, std::function<void()> >& GetProblems();
bool RegisterProblem( std::string s, std::function<void()> ); // always returns true
// In problem1.cpp:
void Problem1(); // implement this!
bool bProblem1Registered = RegisterProblem( "Problem1", Problem1 );
// In problem2.cpp:
void Problem2(); // implement this!
bool bProblem2Registered = RegisterProblem( "Problem2", Problem2 );
// etc
// in main.cpp:
int main(int argc, char** argv)
{
if (argc == 0)
return -1; // and maybe print help
auto it = GetProblems().find( argv[1] );
if (it == GetProblems().end())
return -1; // and maybe print help
it->second(); // call the problem
}
ここでは、不要なクラス階層を排除し、文字列とvoid()
関数の間のマップを維持するだけです。このマップの保守は、関数が記述されている各場所に分散されているため、中央のリストやifステートメントはありません。
上記のような粗雑なコードで何も出荷しませんが、あなたがアイデアを理解してくれることを願っています。