Robotics StackExchange | Archived questions

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

Comments

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