我相信@NPE 的回答是非常合理的,我怀疑它对你的应用来说太过分了,正如你所暗示的那样。
考虑以下示例:假设您的“引擎”逻辑(即:应用程序的功能)包含在名为 engine.hpp 的文件中:
// this is engine.hpp
#pragma once
#include <iostream>
void standalone() {
std::cout << "called standalone" << std::endl;
}
struct Foo {
static void first() {
std::cout << "called Foo::first()" << std::endl;
}
static void second() {
std::cout << "called Foo::second()" << std::endl;
}
};
// other functions...
假设您想根据地图调度不同的功能:
"standalone" dispatches void standalone()
"first" dispatches Foo::first()
"second" dispatches Foo::second()
# other dispatch rules...
您可以使用以下 gperf 输入文件(我称之为“lookups.gperf”)来做到这一点:
%{
#include "engine.hpp"
struct CommandMap {
const char *name;
void (*dispatch) (void);
};
%}
%ignore-case
%language=C++
%define class-name Commands
%define lookup-function-name Lookup
struct CommandMap
%%
standalone, standalone
first, Foo::first
second, Foo::second
然后你可以使用 gperf 使用一个简单的命令创建一个lookups.hpp 文件:
gperf -tCG lookups.gperf > lookups.hpp
一旦我设置好了,下面的main 子例程将根据我输入的内容调度命令:
#include <iostream>
#include "engine.hpp" // this is my application engine
#include "lookups.hpp" // this is gperf's output
int main() {
std::string command;
while(std::cin >> command) {
auto match = Commands::Lookup(command.c_str(), command.size());
if(match) {
match->dispatch();
} else {
std::cerr << "invalid command" << std::endl;
}
}
}
编译:
g++ main.cpp -std=c++11
并运行它:
$ ./a.out
standalone
called standalone
first
called Foo::first()
Second
called Foo::second()
SECOND
called Foo::second()
first
called Foo::first()
frst
invalid command
请注意,一旦您生成了lookups.hpp,您的应用程序在 gperf 中就没有任何依赖关系了。
免责声明:这个例子的灵感来自this site。