在构造函数中将 class 成员函数分配给映射
Assigning a class member function to a map, in the constructor
我有一个 class 成员函数需要根据整数值调用其他 class 成员函数,如下所示:
class foo {
public:
foo() {
mTestMap[1] = (*this).test1;
mTestMap[2] = (*this).test2;
mTestMap[3] = (*this).test3;
}
bool test1 () {}
bool test2 () {}
bool test3 () {}
bool execute_test(int test_num) {
if (mTestMap.count(test_num) > 0)
return mTestMap[test_num]();
return false;
}
std::map<int,std::function<bool()>> mTestMap;
};
问题是,这段代码会导致编译错误:
Error C3867 'foo::test1': non-standard syntax; use '&' to create a pointer to member
我做错了什么?我知道我可以通过指向特定对象的指针将成员函数分配给 std::function
。如果映射和分配发生在 class 之外,则类似的方法会起作用。为什么不从 class 里面?
使用 std::bind
或 lambda:
mTestMap[1] = [](){ return (*this).test1(); };
std::function<bool()>
此 std::function
包装了一个不带参数且 returns 为 bool
的可调用对象。就是这个意思。
bool test1 () {}
您会惊讶地发现,这实际上不是一个不带参数的函数,而且 returns 是 bool
。这是一个 class 方法 不带参数和 returns 布尔值。很大的区别。因此,编译错误。
有两种基本方法可以正确使用这种调度:
最简单的就是用std::bind
:
mTestMap[1] = std::bind(&foo::test1, this);
mTestMap[2] = std::bind(&foo::test2, this);
mTestMap[3] = std::bind(&foo::test3, this);
它的一个变体将使用 lambda,但这相当于同一件事。这是最简单的改变。但是,如果此 class 的实例被复制或移动,它会非常、非常快地向南移动。
使用 class 方法指针的映射。这需要更多的工作:
std::map<int, bool (foo::*)()> mTestMap;
// ...
mTestMap[1] = &foo::test1;
mTestMap[2] = &foo::test2;
mTestMap[3] = &foo::test3;
// ...
bool execute_test(int test_num) {
if (mTestMap.count(test_num) > 0)
return (this->*mTestMap[test_num])();
return false;
使用这种方法,在复制或移动此 class 的实例后,意想不到的惊喜会更少。
我有一个 class 成员函数需要根据整数值调用其他 class 成员函数,如下所示:
class foo {
public:
foo() {
mTestMap[1] = (*this).test1;
mTestMap[2] = (*this).test2;
mTestMap[3] = (*this).test3;
}
bool test1 () {}
bool test2 () {}
bool test3 () {}
bool execute_test(int test_num) {
if (mTestMap.count(test_num) > 0)
return mTestMap[test_num]();
return false;
}
std::map<int,std::function<bool()>> mTestMap;
};
问题是,这段代码会导致编译错误:
Error C3867 'foo::test1': non-standard syntax; use '&' to create a pointer to member
我做错了什么?我知道我可以通过指向特定对象的指针将成员函数分配给 std::function
。如果映射和分配发生在 class 之外,则类似的方法会起作用。为什么不从 class 里面?
使用 std::bind
或 lambda:
mTestMap[1] = [](){ return (*this).test1(); };
std::function<bool()>
此 std::function
包装了一个不带参数且 returns 为 bool
的可调用对象。就是这个意思。
bool test1 () {}
您会惊讶地发现,这实际上不是一个不带参数的函数,而且 returns 是 bool
。这是一个 class 方法 不带参数和 returns 布尔值。很大的区别。因此,编译错误。
有两种基本方法可以正确使用这种调度:
最简单的就是用
std::bind
:mTestMap[1] = std::bind(&foo::test1, this); mTestMap[2] = std::bind(&foo::test2, this); mTestMap[3] = std::bind(&foo::test3, this);
它的一个变体将使用 lambda,但这相当于同一件事。这是最简单的改变。但是,如果此 class 的实例被复制或移动,它会非常、非常快地向南移动。
使用 class 方法指针的映射。这需要更多的工作:
std::map<int, bool (foo::*)()> mTestMap; // ... mTestMap[1] = &foo::test1; mTestMap[2] = &foo::test2; mTestMap[3] = &foo::test3; // ... bool execute_test(int test_num) { if (mTestMap.count(test_num) > 0) return (this->*mTestMap[test_num])(); return false;
使用这种方法,在复制或移动此 class 的实例后,意想不到的惊喜会更少。