假设我有一个带有两个成员函数的类:
#include <string>
#include <vector>
using namespace std;
class MyClass{
MyClass(){
MyCommandServer server;
server.addToCollection(&[](string a)->string{return helloWorld();});
server.addToCollection(&[](string a)->string{return to_string(add(stoi(a[0]),stoi(a[1])));});
while(true){
server.pollForCommand();
doSomethingElse();
}
}
string helloWorld(){
return "Hello World!";
}
int add(int a, int b){
return a+b;
}
};
第一个实例化的另一个类:
typedef string (*MyFunctionPointer)(string);
class MyCommandServer{
MyCommandServer(){}
void addToCollection(MyFunctionPointer ptr){
functionCollection.push_back(ptr);
}
void pollForCommand(){
string newCommand = checkForCommand(&args);
if(newCommand.size()&&isValidCommand(newCommand[0])){
sendResponseToClient(functionCollection[newCommand[0]](newCommand.substr(1)));
}
}
string checkForCommand();
bool isValidCommand(char);
void sendResponseToClient(string);
vector<MyFunctionPointer> functionCollection;
};
如何将前两个方法传递给addToCollection(MyFunctionPointer)?我想知道是否可以按照示例进行操作。我的目标是要有一种仅在容器中使用索引调用MyClass函数的方法,并通过提供的lambda函数弄清楚如何使用提供的参数(如果有的话)。这应该启用Command Server类,在该类中,我通过UDP获得一个char作为上述索引,并获得一个参数(如果有)作为字符串。
但是,编译器不允许我传递对lambda的引用。
在MyServerClass中进行switch-case语句是不可行的,因为Server类不知道其父方法,因此我在该示例中手动输入了在示例中放入lambda的代码。
是否可以提供与示例类似的内容?
很抱歉,如果该帖子没有达到标准,这是我的第一个帖子。
感谢您的帮助!
答案 0 :(得分:0)
lambda方法不起作用的原因是,如果lambda没有捕获,则只能将lambda转换为函数指针。但是,要在lambda中使用/包装(非静态)成员函数,lambda必须捕获(存储)特定对象实例以在(this
上调用该成员函数,并且函数指针不能具有(非-global)这样的存储状态。如果将this
添加到捕获列表,则lambda本身是有效的,但不能再衰减到函数指针。
std::function
允许您存储任意可调用对象-即使是带有捕获的对象。它们也往往比函数指针更具可读性(和更高层次)。
using MyFunctionType = std::function<std::string(std::string)>;
class MyCommandServer
{
void addToCollection(MyFunctionType fnc){
functionCollection.push_back(fnc);
}
// ...
vector<MyFunctionType> functionCollection;
}
现在MyCommandServer
可以接受并存储您的lambda(如果您按值传递它们),因为可以使用字符串参数调用它们并返回一个字符串。