如何使用 Visual Studio 2008 将字符串映射到函数?
How to map a string to a function with Visual Studio 2008?
此问题引用了以下问题:
Using a STL map of function pointers
在 C++11 中,我使用映射来存储 <string, function>
对以更有效地执行代码,而不是使用 link 提到的 if...else if...else if
。
代码封装在成员函数中,其中this
指的是class,允许访问成员变量。
using f = std::function<void()>;
static const std::map<std::string, f> doSumthin{
{"case 1", [this]() {
// execute code in case 1
}},
{"case 2", [this]() {
// execute code in case 2
}},
…
};
auto it = doSumthin.find(someString);
if (it != doSumthin.end())
{
it->second();
}
但是,我需要使代码库在 VS 2008 中工作。我不确定在不恢复到效率较低的情况下复制上述代码以在 VS 2008 中工作的最佳方法是什么if...else if
.
关于这个问题,我可以获得一些指导吗?
#include <map>
#include <string>
typedef void (*func_ptr_type)();
void func_case_1() {}
void func_case_2() {}
static std::map<std::string, func_ptr_type> doSumthin;
void initMap()
{
doSumthin["case 1"] = func_case_1;
doSumthin["case 2"] = func_case_2;
}
int main()
{
initMap();
std::map<std::string, func_ptr_type>::iterator it = doSumthin.find("case 1");
if (it != doSumthin.end())
{
it->second();
}
return 0;
}
我没有在 VS2008 上专门测试过它,但我相当确定它是有效的 C++98。
#include <map>
#include <string>
class Foo {
void case_1() {}
void case_2() {}
typedef std::map<std::string, void(Foo::*)()> CaseMap;
static CaseMap initCases() {
CaseMap cases;
cases["case_1"] = &Foo::case_1;
cases["case_2"] = &Foo::case_2;
return cases;
}
static const CaseMap cases;
public:
void execute(const std::string &name) {
CaseMap::const_iterator iter = cases.find(name);
if (iter != cases.end()) {
void(Foo::*func)() = iter->second;
(this->*func)();
}
}
};
const Foo::CaseMap Foo::cases = Foo::initCases();
另一种可能是使用X-macros。我相信这与 C++11 片段最接近(但我不建议使用它)。
#define CASES(X) \
X(case_1, { \
/* do case 1 */ \
}) \
X(case_2, { \
/* do case 2 */ \
})
#define DEFINE_FUNCTION(NAME, CODE) void NAME() CODE
#define INIT_MAP(NAME, CODE) cases[#NAME] = &Bar::NAME;
class Bar {
CASES(DEFINE_FUNCTION)
typedef std::map<std::string, void(Bar::*)()> CaseMap;
static CaseMap initCases() {
CaseMap cases;
CASES(INIT_MAP)
return cases;
}
static const CaseMap cases;
public:
void execute(const std::string &name) {
CaseMap::const_iterator iter = cases.find(name);
if (iter != cases.end()) {
void(Bar::*func)() = iter->second;
(this->*func)();
}
}
};
const Bar::CaseMap Bar::cases = Bar::initCases();
此问题引用了以下问题: Using a STL map of function pointers
在 C++11 中,我使用映射来存储 <string, function>
对以更有效地执行代码,而不是使用 link 提到的 if...else if...else if
。
代码封装在成员函数中,其中this
指的是class,允许访问成员变量。
using f = std::function<void()>;
static const std::map<std::string, f> doSumthin{
{"case 1", [this]() {
// execute code in case 1
}},
{"case 2", [this]() {
// execute code in case 2
}},
…
};
auto it = doSumthin.find(someString);
if (it != doSumthin.end())
{
it->second();
}
但是,我需要使代码库在 VS 2008 中工作。我不确定在不恢复到效率较低的情况下复制上述代码以在 VS 2008 中工作的最佳方法是什么if...else if
.
关于这个问题,我可以获得一些指导吗?
#include <map>
#include <string>
typedef void (*func_ptr_type)();
void func_case_1() {}
void func_case_2() {}
static std::map<std::string, func_ptr_type> doSumthin;
void initMap()
{
doSumthin["case 1"] = func_case_1;
doSumthin["case 2"] = func_case_2;
}
int main()
{
initMap();
std::map<std::string, func_ptr_type>::iterator it = doSumthin.find("case 1");
if (it != doSumthin.end())
{
it->second();
}
return 0;
}
我没有在 VS2008 上专门测试过它,但我相当确定它是有效的 C++98。
#include <map>
#include <string>
class Foo {
void case_1() {}
void case_2() {}
typedef std::map<std::string, void(Foo::*)()> CaseMap;
static CaseMap initCases() {
CaseMap cases;
cases["case_1"] = &Foo::case_1;
cases["case_2"] = &Foo::case_2;
return cases;
}
static const CaseMap cases;
public:
void execute(const std::string &name) {
CaseMap::const_iterator iter = cases.find(name);
if (iter != cases.end()) {
void(Foo::*func)() = iter->second;
(this->*func)();
}
}
};
const Foo::CaseMap Foo::cases = Foo::initCases();
另一种可能是使用X-macros。我相信这与 C++11 片段最接近(但我不建议使用它)。
#define CASES(X) \
X(case_1, { \
/* do case 1 */ \
}) \
X(case_2, { \
/* do case 2 */ \
})
#define DEFINE_FUNCTION(NAME, CODE) void NAME() CODE
#define INIT_MAP(NAME, CODE) cases[#NAME] = &Bar::NAME;
class Bar {
CASES(DEFINE_FUNCTION)
typedef std::map<std::string, void(Bar::*)()> CaseMap;
static CaseMap initCases() {
CaseMap cases;
CASES(INIT_MAP)
return cases;
}
static const CaseMap cases;
public:
void execute(const std::string &name) {
CaseMap::const_iterator iter = cases.find(name);
if (iter != cases.end()) {
void(Bar::*func)() = iter->second;
(this->*func)();
}
}
};
const Bar::CaseMap Bar::cases = Bar::initCases();