问题描述
我正在尝试为我的一个项目构建一个遥测服务器,该服务器将树莓派与我的本地计算机连接起来。我的想法是拥有一个请求驱动的服务器,然后该服务器捕获所需的数据。因此,我使用boost:signals2来提供名称和适当函数之间的映射。
我在Google上搜索了很多,但是不知何故我无法正常运行。 我发现的“解决方案”是std :: bind,但它或多或少会产生类似的输出。
如何使它正常工作?还是我需要其他方法?
#include <iostream>
#include <string>
#include <boost/signals2.hpp>
#include <boost/ptr_container/ptr_map.hpp>
class message{
private:
std::string data;
public:
void setMessage(std::string mes){data = mes;};
std::string getMessage(){return data;};
};
class telemetry{
public:
boost::ptr_map< std::string,boost::signals2::signal<std::string ()>> container;
};
int main()
{
message A,B;
A.setMessage("AAA");
B.setMessage("BBB");
telemetry T;
T.container["A"].connect(A.getMessage);
T.container["B"].connect(B.getMessage);
std::cout << "A: " << T.container["A"]() << std::endl;
std::cout << "B: " << T.container["B"]() << std::endl;
}
解决方法
您看到此错误的原因与类方法的工作方式有关。
执行该方法的代码的地址为&message::getMessage
。但这不是函数指针,因为类同时具有 code 和 data ,而这只是代码的地址。
要执行该方法,您既需要方法的地址,又需要类数据的地址:
std::string (message::*code)() = &message::getMessage;
message* data = &A;
std::cout << (data->*code)();
无论如何,关键是您不能将类方法视为函数指针,它必须以某种方式绑定到数据。
幸运的是,boost::signals2::signal::connect
不使用函数指针或成员指针。它需要一个boost::function
,这是一个包装类方法,甚至将数据或参数绑定到其上的类。 boost::bind
可以帮助您将方法绑定到数据并返回boost::function
:
T.container["A"].connect(boost::bind(&message::getMessage,A));
T.container["B"].connect(boost::bind(&message::getMessage,B));
如果您使用的是C ++ 11或更高版本,则可以忘记所有这些,因为您可以传递lamba:
T.container["A"].connect([&A](){ return A.getMessage(); });
T.container["B"].connect([&B](){ return B.getMessage(); });
Lambas很棒,因为它们是内置语法,您可以将任何种类的数据传递到其中,引用,值等,并表示任何种类的代码片段,而不仅仅是预定义的函数或类方法。并且您可以将它们传递给boost::function
(或在C ++ 11中,因为它们将其纳入标准std::function
)。