error in using boost::bind to pass parameter
I'm new to ros and boost programming. From ros wiki and google, I know I can use boost::bind to transfer parameter to callback function. So I try to use it build a service server with parameter. But I keep meeting mismatching problem. When I try to find answer in ros community, I only find answers about subscriber. So i pose this question.
the code of bare function:
bool control_test(bebop_test::ControlSrv::Request &req, bebop_test::ControlSrv::Response &res, bebop_command *bebop_cmd){/**/}
code in main:
ros::ServiceServer bebop_server = nh.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2, &bebop_cmd) );
and the error:
> Errors << bebop_test:make
> /home/simon/parrot_ws/logs/bebop_test/build.make.008.log /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:
> In function ‘int main(int, char**)’:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> error: no matching function for call
> to
> ‘ros::NodeHandle::advertiseService(const
> char [10], boost::_bi::bind_t<bool,
> bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> >
> >)’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:879:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool (T::*)(MReq&, MRes&),
> T*) ServiceServer
> advertiseService(const std::string&
> service, bool(T::*srv_func)(MReq &,
> MRes &), T *obj)
> ^ /opt/ros/kinetic/include/ros/node_handle.h:879:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (T::*)(MReq&, MRes&)’ and
> ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:924:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&), T*) ServiceServer
> advertiseService(const std::string&
> service,
> bool(T::*srv_func)(ServiceEvent<MReq,
> MRes>&), T *obj)
> ^ /opt/ros/kinetic/include/ros/node_handle.h:924:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&)’ and ‘boost::_bi::bind_t<bool,
> bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:970:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool (T::*)(MReq&, MRes&),
> const boost::shared_ptr<X>&)
> ServiceServer advertiseService(const
> std::string& service,
> bool(T::*srv_func)(MReq &, MRes &),
> const boost::shared_ptr<T>& obj)
> ^ /opt/ros/kinetic/include/ros/node_handle.h:970:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (T::*)(MReq&, MRes&)’ and
> ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1017:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&), const boost::shared_ptr<X>&)
> ServiceServer advertiseService(const
> std::string& service,
> bool(T::*srv_func)(ServiceEvent<MReq,
> MRes>&), const boost::shared_ptr<T>&
> obj)
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1017:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&)’ and ‘boost::_bi::bind_t<bool,
> bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1061:17:
> note: candidate: template<class MReq,
> class MRes> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool (*)(MReq&, MRes&))
> ServiceServer advertiseService(const
> std::string& service,
> bool(*srv_func)(MReq&, MRes&))
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1061:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (*)(MReq&, MRes&)’ and
> ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1104:17:
> note: candidate: template<class MReq,
> class MRes> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool
> (*)(ros::ServiceEvent<MReq, MRes>&))
> ServiceServer advertiseService(const
> std::string& service,
> bool(*srv_func)(ServiceEvent<MReq,
> MRes>&))
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1104:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: mismatched types ‘bool
> (*)(ros::ServiceEvent<MReq, MRes>&)’
> and ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1145:17:
> note: candidate: template<class MReq,
> class MRes> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, const
> boost::function<bool(MReq&, MRes&)>&,
> const VoidConstPtr&) ServiceServer
> advertiseService(const std::string&
> service, const
> boost::function<bool(MReq&, MRes&)>&
> callback,
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1145:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> is not derived from ‘const
> boost::function<bool(MReq&, MRes&)>’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1190:17:
> note: candidate: template<class S>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, const
> boost::function<bool(S&)>&, const
> VoidConstPtr&) ServiceServer
> advertiseService(const std::string&
> service, const
> boost::function<bool(S&)>& callback,
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1190:17:
> note: template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note: ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
> is not derived from ‘const
> boost::function<bool(S&)>’
> ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
> ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
> from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:1222:17:
> note: candidate: ros::ServiceServer
> ros::NodeHandle::advertiseService(ros::AdvertiseServiceOptions&)
> ServiceServer
> advertiseService(AdvertiseServiceOptions&
> ops);
> ^ /opt/ros/kinetic/include/ros/node_handle.h:1222:17:
> note: candidate expects 1 argument,
> 2 provided make[2]: ***
> [CMakeFiles/bebop_server.dir/src/bebop_server_re.cpp.o] Error 1 make[1]: ***
> [CMakeFiles/bebop_server.dir/all]
> Error 2 make: *** [all] Error 2
Asked by ewjtx on 2018-05-23 11:16:13 UTC
Answers
The template argument deduction fails for advertiseService when using boost::bind (see https://answers.ros.org/question/233525/template-argument-deduction-fails/), so you need to be more explicit:
#include <ros/ros.h>
#include <std_srvs/SetBool.h>
bool test(std_srvs::SetBool::Request& req, std_srvs::SetBool::Response& resp)
{
return true;
}
bool test2(std_srvs::SetBool::Request& req, std_srvs::SetBool::Response& resp,
bool toggle)
{
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "node");
ros::NodeHandle nh;
// works without template parameters
ros::ServiceServer service0 = nh.advertiseService("my_service0", test);
// compile error: no matching function for call to ‘ros::NodeHandle::advertiseService...
// ros::ServiceServer service1 = nh.advertiseService("my_service1",
// boost::bind(&test2, _1, _2, false));
ros::ServiceServer service2 = nh.advertiseService<std_srvs::SetBool::Request,
std_srvs::SetBool::Response>("my_service2",
boost::bind(&test2, _1, _2, true));
ros::spin();
return 0;
}
Asked by lucasw on 2018-05-24 08:18:53 UTC
Comments