I was making some modifications to a boost::asio project today and I ran into a confusing compilation error when attempting to pass a bound function into an async call.
I have spent hours fiddling with this code, so I suspect I am missing something stupid. I would appreciate anyone who can point out where I am going wrong.
error: no match for call to ‘(boost::_mfi::mf3<void, ClientServerManager,
const MCServer&, boost::shared_ptr<Connection>,
const boost::system::error_code&>) (ClientServerManager*&,
MCServer&, boost::shared_ptr<Connection>&,
const MCServer&)’
Notice that const MCServer& appears twice? That isn't how my bind statement is written:
void ClientServerManager::onConnect(const MCServer& server_info,
boost::shared_ptr<Connection> con,
const boost::system::error_code& err,
tcp::resolver::iterator i) {
// Instruct utility to do some work, and call our function when complete.
con->statusPing(
boost::bind( // <-- OFFENDING CODE
&ClientServerManager::onPingCompletion,
this,
server_info,
con, // shared_ptr to connection (maintains scope)
boost::asio::placeholders::error // in case of a downstream failure
)
);
}
In the Connection header statusPing(...) is defined as follows:
void statusPing(boost::function<
void(
MCServer&, boost::shared_ptr<Connection>,
const boost::system::error_code&
)>);
The handler eventually to be called:
void ClientServerManager::onPingCompletion(
const MCServer& server_info,
boost::shared_ptr<Connection>,
const boost::system::error_code& err){
// Use the results to drive some function...
}
Background:
I have a class which iterates through a list of servers and opens
short-lived connections with them to make sure they are operating
properly.
The class uses a utility, Connection which inherits
boost::enable_shared_from_this. Therefore, I call a function, Connection::create(..) to grab a boost::shared_ptr to start work with. When any async calls are made, this pointer has to be passed to keep the connection in scope.
In this instance after the connection is successfully established, I want to pass execution to Connection such that it can execute some tasks, and I want it to call a handle once those tasks are complete. I cannot get boost::bind to compile properly in this case.
Now the issue I am having is that the boost::bind might be linked to the use of the boost::asio::placeholders::error template.
The full output follows:
g++ -std=c++0x -DBOOST_LOG_DYN_LINK -I/home/donald/Desktop/workspace/MCProxy/Debug/ -O3 -march=corei7-avx -g1 -w -c -fmessage-length=0 -MMD -MP -MF"src/ClientServerManager.d" -MT"src/ClientServerManager.d" -o "src/ClientServerManager.o" "../src/ClientServerManager.cpp"
In file included from ....
/boost/bind/bind.hpp: In instantiation of ‘void boost::_bi::list4<A1, A2, A3, A4>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>; A = boost::_bi::list3<const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>; A1 = boost::_bi::value<ClientServerManager*>; A2 = boost::_bi::value<MCServer>; A3 = boost::_bi::value<boost::shared_ptr<Connection> >; A4 = boost::arg<1> (*)()]’:
/boost/bind/bind_template.hpp:116:59: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&, A2&, A3&) [with A1 = const MCServer; A2 = boost::shared_ptr<Connection>; A3 = const boost::system::error_code; R = void; F = boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>; L = boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]’
/boost/function/function_template.hpp:153:11: required from ‘static void boost::detail::function::void_function_obj_invoker3<FunctionObj, R, T0, T1, T2>::invoke(boost::detail::function::function_buffer&, T0, T1, T2) [with FunctionObj = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; T0 = const MCServer&; T1 = boost::shared_ptr<Connection>; T2 = const boost::system::error_code&]’
/boost/function/function_template.hpp:934:60: required from ‘void boost::function3<R, T1, T2, T3>::assign_to(Functor) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; T0 = const MCServer&; T1 = boost::shared_ptr<Connection>; T2 = const boost::system::error_code&]’
/boost/function/function_template.hpp:722:7: required from ‘boost::function3<R, T1, T2, T3>::function3(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; T0 = const MCServer&; T1 = boost::shared_ptr<Connection>; T2 = const boost::system::error_code&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/boost/function/function_template.hpp:1071:16: required from ‘boost::function<R(T0, T1, T2)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; T0 = const MCServer&; T1 = boost::shared_ptr<Connection>; T2 = const boost::system::error_code&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
../src/ClientServerManager.cpp:90:3: required from here
/boost/bind/bind.hpp:457:9: error: no match for call to ‘(boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>, const boost::system::error_code&>) (ClientServerManager*&, MCServer&, boost::shared_ptr<Connection>&, const MCServer&)’
In file included ....
/boost/bind/mem_fn_template.hpp:366:85: note: candidates are:
/boost/bind/mem_fn_template.hpp:391:7: note: R boost::_mfi::mf3<R, T, A1, A2, A3>::operator()(T*, A1, A2, A3) const [with R = void; T = ClientServerManager; A1 = const MCServer&; A2 = boost::shared_ptr<Connection>; A3 = const boost::system::error_code&]
/boost/bind/mem_fn_template.hpp:391:7: note: no known conversion for argument 4 from ‘const MCServer’ to ‘const boost::system::error_code&’
/boost/bind/mem_fn_template.hpp:396:25: note: template<class U> R boost::_mfi::mf3::operator()(U&, A1, A2, A3) const [with U = U; R = void; T = ClientServerManager; A1 = const MCServer&; A2 = boost::shared_ptr<Connection>; A3 = const boost::system::error_code&]
/boost/bind/mem_fn_template.hpp:396:25: note: template argument deduction/substitution failed:
In file included ....
/boost/bind/bind.hpp:457:9: note: cannot convert ‘(& a)->boost::_bi::list3<A1, A2, A3>::operator[]<const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>(boost::_bi::storage4<A1, A2, A3, boost::arg<I> (*)()>::a4_<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, 1>)’ (type ‘const MCServer’) to type ‘const boost::system::error_code&’
In file included ....
/boost/bind/mem_fn_template.hpp:404:25: note: template<class U> R boost::_mfi::mf3::operator()(const U&, A1, A2, A3) const [with U = U; R = void; T = ClientServerManager; A1 = const MCServer&; A2 = boost::shared_ptr<Connection>; A3 = const boost::system::error_code&]
/boost/bind/mem_fn_template.hpp:404:25: note: template argument deduction/substitution failed:
In file included ....
/boost/bind/bind.hpp:457:9: note: cannot convert ‘(& a)->boost::_bi::list3<A1, A2, A3>::operator[]<const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>(boost::_bi::storage4<A1, A2, A3, boost::arg<I> (*)()>::a4_<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, 1>)’ (type ‘const MCServer’) to type ‘const boost::system::error_code&’
In file included from ....
/boost/bind/mem_fn_template.hpp:412:7: note: R boost::_mfi::mf3<R, T, A1, A2, A3>::operator()(T&, A1, A2, A3) const [with R = void; T = ClientServerManager; A1 = const MCServer&; A2 = boost::shared_ptr<Connection>; A3 = const boost::system::error_code&]
/boost/bind/mem_fn_template.hpp:412:7: note: no known conversion for argument 1 from ‘ClientServerManager*’ to ‘ClientServerManager&’
Edit: (boost::function<void(...)> -> boost::function<void()>)
Per suggestion, I changed the Connection function to read void statusPing(boost::function<void()>); as the parameters are bound in. This change yields a different error:
g++ -std=c++0x -DBOOST_LOG_DYN_LINK -I/home/donald/Desktop/workspace/MCProxy/Debug/ -O3 -march=corei7-avx -g1 -w -c -fmessage-length=0 -MMD -MP -MF"src/ClientServerManager.d" -MT"src/ClientServerManager.d" -o "src/ClientServerManager.o" "../src/ClientServerManager.cpp"
In file included from ....
/boost/bind/bind.hpp: In instantiation of ‘void boost::_bi::list4<A1, A2, A3, A4>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>; A = boost::_bi::list0; A1 = boost::_bi::value<ClientServerManager*>; A2 = boost::_bi::value<MCServer>; A3 = boost::_bi::value<boost::shared_ptr<Connection> >; A4 = boost::arg<1> (*)()]’:
/boost/bind/bind_template.hpp:20:59: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void; F = boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>; L = boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]’
/boost/function/function_template.hpp:153:11: required from ‘static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void]’
/boost/function/function_template.hpp:934:60: required from ‘void boost::function0<R>::assign_to(Functor) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void]’
/boost/function/function_template.hpp:722:7: required from ‘boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/boost/function/function_template.hpp:1071:16: required from ‘boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = boost::_bi::bind_t<void, boost::_mfi::mf3<void, ClientServerManager, const MCServer&, boost::shared_ptr<Connection>&, const boost::system::error_code&>, boost::_bi::list4<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, boost::arg<1> (*)()> >; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
../src/ClientServerManager.cpp:90:2: required from here
/boost/bind/bind.hpp:457:9: error: no match for ‘operator[]’ in ‘a[boost::_bi::storage4<A1, A2, A3, boost::arg<I> (*)()>::a4_<boost::_bi::value<ClientServerManager*>, boost::_bi::value<MCServer>, boost::_bi::value<boost::shared_ptr<Connection> >, 1>]’
/boost/bind/bind.hpp:457:9: note: candidates are:
In file included ....
/boost/bind/bind.hpp:170:27: note: template<class T> T& boost::_bi::list0::operator[](boost::_bi::value<T>&) const
/boost/bind/bind.hpp:170:27: note: template argument deduction/substitution failed:
In file included ....
/boost/bind/bind.hpp:457:9: note: mismatched types ‘boost::_bi::value<T>’ and ‘boost::arg<1>()’
In file included ....
/boost/bind/bind.hpp:172:33: note: template<class T> const T& boost::_bi::list0::operator[](const boost::_bi::value<T>&) const
/boost/bind/bind.hpp:172:33: note: template argument deduction/substitution failed:
In file included ....
/boost/bind/bind.hpp:457:9: note: mismatched types ‘const boost::_bi::value<T>’ and ‘boost::arg<1>()’
In file included ....
/boost/bind/bind.hpp:174:27: note: template<class T> T& boost::_bi::list0::operator[](const boost::reference_wrapper<T>&) const
/boost/bind/bind.hpp:174:27: note: template argument deduction/substitution failed:
In file included from ....
/boost/bind/bind.hpp:457:9: note: mismatched types ‘const boost::reference_wrapper<T>’ and ‘boost::arg<1>()’
In file included from ....
/boost/bind/bind.hpp:176:76: note: template<class R, class F, class L> typename boost::_bi::result_traits<R, F>::type boost::_bi::list0::operator[](boost::_bi::bind_t<R, F, L>&) const
/boost/bind/bind.hpp:176:76: note: template argument deduction/substitution failed:
In file included from ....
/boost/bind/bind.hpp:457:9: note: mismatched types ‘boost::_bi::bind_t<R, F, L>’ and ‘boost::arg<1>()’
/boost/bind/bind.hpp:178:76: note: template<class R, class F, class L> typename boost::_bi::result_traits<R, F>::type boost::_bi::list0::operator[](const boost::_bi::bind_t<R, F, L>&) const
/boost/bind/bind.hpp:178:76: note: template argument deduction/substitution failed:
/boost/bind/bind.hpp:457:9: note: mismatched types ‘const boost::_bi::bind_t<R, F, L>’ and ‘boost::arg<1>()’
make: *** [src/ClientServerManager.o] Error 1
A simplified example:
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <boost/function.hpp>
class ExampleWorker {
public:
void statusPing(boost::function<void()> f){
// Do work.
f(); // Call handle
}
};
class SomeObject {};
void someHandle(boost::shared_ptr<SomeObject> obj,
const boost::system::error_code& err){
// ...
}
int main() {
ExampleWorker* e = new ExampleWorker();
boost::shared_ptr<SomeObject> ptr(new SomeObject());
e->statusPing(
boost::bind(
&someHandle,
ptr,
boost::asio::placeholders::error
)
);
}
boost::asio::placeholders::error is just like using boost::placeholders::_1 with boost::bind, and when you pass a bind expression containing that to an asio completion handler function, the function will invoke your handler with the boost::system::error_code result from the operation it performed, thus allowing your handler access to the error code.
In your second example, the boost::function signature for the following bind expression
boost::bind(
&someHandle,
ptr,
boost::asio::placeholders::error
)
is
boost::function<void(boost::system::error_code const&)>
To get your code to compile, change the statusPing() member function to
void statusPing(boost::function<void(boost::system::error_code const&)> f){
// Do work.
boost::system::error_code err;
f(err); // Call handle
}
Related
rand_dat1_sub_handle = node.subscribe<geometry_msgs::Vector3>(
"random/data1", 100,
[](geometry_msgs::Vector3::ConstPtr& data){std::cout<<data->x;});
rand_dat2_sub_handle = node.subscribe<geometry_msgs::Vector3>(
"random/data2", 100,
[](geometry_msgs::Vector3::ConstPtr& data){std::cout<<data->x;});
when I use the above block of code in my class definition script, my build fails giving me the following errors.
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/melodic/include/ros/forwards.h:40,
from /opt/ros/melodic/include/ros/common.h:37,
from /opt/ros/melodic/include/ros/ros.h:43,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.h:7,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:2:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:925:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:716:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/include/boost/function/function_template.hpp:1061:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:85:83: required from here
/usr/include/boost/function/function_template.hpp:159:11: error: no match for call to ‘(TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>) (const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&)’
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
^
/usr/include/boost/function/function_template.hpp:159:11: note: candidate: void (*)(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&) {aka void (*)(boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&)} <conversion>
/usr/include/boost/function/function_template.hpp:159:11: note: conversion of argument 2 would be ill-formed:
/usr/include/boost/function/function_template.hpp:159:11: error: binding reference of type ‘geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr& {aka boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&}’ to ‘const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >’ discards qualifiers
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:85:50: note: candidate: TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)> <near match>
[](geometry_msgs::Vector3::ConstPtr& data){std::cout<<data->x<<std::endl;});
^
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:85:50: note: conversion of argument 1 would be ill-formed:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/melodic/include/ros/forwards.h:40,
from /opt/ros/melodic/include/ros/common.h:37,
from /opt/ros/melodic/include/ros/ros.h:43,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.h:7,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:2:
/usr/include/boost/function/function_template.hpp:159:11: error: binding reference of type ‘geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr& {aka boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&}’ to ‘const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >’ discards qualifiers
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
^
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:925:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:716:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/include/boost/function/function_template.hpp:1061:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type) [with Functor = TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>; R = void; T0 = const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&; typename boost::enable_if_c<(! boost::is_integral<Functor>::value), int>::type = int]’
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:89:83: required from here
/usr/include/boost/function/function_template.hpp:159:11: error: no match for call to ‘(TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)>) (const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&)’
/usr/include/boost/function/function_template.hpp:159:11: note: candidate: void (*)(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&) {aka void (*)(boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&)} <conversion>
/usr/include/boost/function/function_template.hpp:159:11: note: conversion of argument 2 would be ill-formed:
/usr/include/boost/function/function_template.hpp:159:11: error: binding reference of type ‘geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr& {aka boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&}’ to ‘const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >’ discards qualifiers
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:89:50: note: candidate: TCPServer::TCPServer(ros::NodeHandle*, QObject*)::<lambda(geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr&)> <near match>
[](geometry_msgs::Vector3::ConstPtr& data){std::cout<<data->x<<std::endl;});
^
/home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:89:50: note: conversion of argument 1 would be ill-formed:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/melodic/include/ros/forwards.h:40,
from /opt/ros/melodic/include/ros/common.h:37,
from /opt/ros/melodic/include/ros/ros.h:43,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.h:7,
from /home/hari/workspace/catkin_ws/src/gui_pkg/src/tcpserver.cpp:2:
/usr/include/boost/function/function_template.hpp:159:11: error: binding reference of type ‘geometry_msgs::Vector3_<std::allocator<void> >::ConstPtr& {aka boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >&}’ to ‘const boost::shared_ptr<const geometry_msgs::Vector3_<std::allocator<void> > >’ discards qualifiers
BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
^
gui_pkg/CMakeFiles/TCPSERVER.dir/build.make:62: recipe for target 'gui_pkg/CMakeFiles/TCPSERVER.dir/src/tcpserver.cpp.o' failed
make[2]: *** [gui_pkg/CMakeFiles/TCPSERVER.dir/src/tcpserver.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:1735: recipe for target 'gui_pkg/CMakeFiles/TCPSERVER.dir/all' failed
make[1]: *** [gui_pkg/CMakeFiles/TCPSERVER.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
when i used the regular function callback as shown below, it works fine
rand_dat1_sub_handle = node.subscribe<geometry_msgs::Vector3>(
"random/data1", 100,
&TCPServer::update_data1, this);
How do I use lamdas properly to represent callbacks in subscriber nodes?
I've edited the question showing the new errors after switching from geometry_msgs::Vector3Ptr& to geometry_msgs::Vector3::ConstPtr&.
The following code compiles and runs with the expected results ( 'done' on console after 3 seconds ) when build in codeblocks v17 with 32 bit g++ v5.1 and boost v1.63
#include <iostream>
#include <thread>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
namespace pinmed
{
class cTimedEvent
{
public:
cTimedEvent( boost::asio::io_service& ios )
: myTimer( ios )
{
}
/** Schedule one-off timed event
#param[in] msecs delay from now
#param[in] handler to call when delay expires
*/
template<
typename H >
void Schedule(
int msecs,
H handler )
{
myTimer.expires_from_now(
boost::posix_time::milliseconds( msecs ));
myTimer.async_wait( handler );
}
private:
boost::asio::deadline_timer myTimer;
};
class cClass
{
public:
cClass( boost::asio::io_service& ios )
: myTimedEvent( ios )
{
myTimedEvent.Schedule(
3000,
boost::bind(
&cClass::handler,
this,
boost::asio::placeholders::error) );
}
void handler(
const boost::system::system_error& e)
{
std::cout << "done\n";
}
private:
cTimedEvent myTimedEvent;
};
}
using namespace std;
int main()
{
boost::asio::io_service ios;
pinmed::cClass theClass( ios );
ios.run();
return 0;
}
However, when I "upgrade" to 64 bit g++ v8.2 with boost v1.69 then I get a horrible compiler error:
-------------- Build: Debug in test_timed (compiler: GNU GCC Compiler)---------------
g++.exe -Wall -fexceptions -g -std=c++11 -IC:\Users\James\code\boost\boost_1_69_0 -c C:\Users\James\code\test_timed\main.cpp -o obj\Debug\main.o
g++.exe -LC:\Users\James\code\boost\v1_63_gcc51\stage\lib -LC:\Users\James\code\nana-1.6.2\build\codeblocks -o \bin\test_timed.exe obj\Debug\main.o -lboost_thread-mgw51-mt-1_63 -lboost_system-mgw51-mt-1_63 -lboost_program_options-mgw51-mt-1_63 -lboost_filesystem-mgw51-mt-1_63 -lws2_32
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp: In instantiation of 'void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>; A = boost::_bi::rrlist1<const boost::system::error_code&>; A1 = boost::_bi::value<pinmed::cClass*>; A2 = boost::arg<1> (*)()]':
C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:1306:50: required from 'boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = const boost::system::error_code&; R = void; F = boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>; L = boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/bind_handler.hpp:65:5: required from 'void boost::asio::detail::binder1<Handler, Arg1>::operator()() [with Handler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >; Arg1 = boost::system::error_code]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/handler_invoke_hook.hpp:69:11: required from 'void boost::asio::asio_handler_invoke(Function&, ...) [with Function = boost::asio::detail::binder1<boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >, boost::system::error_code>]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/handler_invoke_helpers.hpp:37:22: required from 'void boost_asio_handler_invoke_helpers::invoke(Function&, Context&) [with Function = boost::asio::detail::binder1<boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >, boost::system::error_code>; Context = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/handler_work.hpp:82:46: required from 'void boost::asio::detail::handler_work<Handler, boost::asio::system_executor>::complete(Function&, Handler&) [with Function = boost::asio::detail::binder1<boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >, boost::system::error_code>; Handler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/wait_handler.hpp:72:7: required from 'static void boost::asio::detail::wait_handler<Handler>::do_complete(void*, boost::asio::detail::operation*, const boost::system::error_code&, std::size_t) [with Handler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >; boost::asio::detail::operation = boost::asio::detail::win_iocp_operation; std::size_t = long long unsigned int]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/wait_handler.hpp:39:15: required from 'boost::asio::detail::wait_handler<Handler>::wait_handler(Handler&) [with Handler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/detail/deadline_timer_service.hpp:236:11: required from 'void boost::asio::detail::deadline_timer_service<Time_Traits>::async_wait(boost::asio::detail::deadline_timer_service<Time_Traits>::implementation_type&, Handler&) [with Handler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >; Time_Traits = boost::asio::time_traits<boost::posix_time::ptime>]'
C:\Users\James\code\boost\boost_1_69_0/boost/asio/basic_deadline_timer.hpp:610:5: required from 'typename boost::asio::async_result<typename std::decay<_U1>::type, void(boost::system::error_code)>::return_type boost::asio::basic_deadline_timer<Time, TimeTraits>::async_wait(WaitHandler&&) [with WaitHandler = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >&; Time = boost::posix_time::ptime; TimeTraits = boost::asio::time_traits<boost::posix_time::ptime>; typename boost::asio::async_result<typename std::decay<_U1>::type, void(boost::system::error_code)>::return_type = void]'
C:\Users\James\code\test_timed\main.cpp:31:9: required from 'void pinmed::cTimedEvent::Schedule(int, H) [with H = boost::_bi::bind_t<void, boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>, boost::_bi::list2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()> >]'
C:\Users\James\code\test_timed\main.cpp:49:51: required from here
C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:319:35: error: no match for call to '(boost::_mfi::mf1<void, pinmed::cClass, const boost::system::system_error&>) (pinmed::cClass*&, const boost::system::error_code&)'
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn.hpp:215,
from C:\Users\James\code\boost\boost_1_69_0/boost/mem_fn.hpp:22,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:26,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:163:7: note: candidate: 'R boost::_mfi::mf1<R, T, A1>::operator()(T*, A1) const [with R = void; T = pinmed::cClass; A1 = const boost::system::system_error&]'
R operator()(T * p, A1 a1) const
^~~~~~~~
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:163:7: note: no known conversion for argument 2 from 'const boost::system::error_code' to 'const boost::system::system_error&'
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:168:25: note: candidate: 'template<class U> R boost::_mfi::mf1<R, T, A1>::operator()(U&, A1) const [with U = U; R = void; T = pinmed::cClass; A1 = const boost::system::system_error&]'
template<class U> R operator()(U & u, A1 a1) const
^~~~~~~~
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:168:25: note: template argument deduction/substitution failed:
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:319:35: note: cannot convert '(& a)->boost::_bi::rrlist1<const boost::system::error_code&>::operator[](boost::_bi::storage2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()>::a2_)' (type 'const boost::system::error_code') to type 'const boost::system::system_error&'
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn.hpp:215,
from C:\Users\James\code\boost\boost_1_69_0/boost/mem_fn.hpp:22,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:26,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:176:25: note: candidate: 'template<class U> R boost::_mfi::mf1<R, T, A1>::operator()(const U&, A1) const [with U = U; R = void; T = pinmed::cClass; A1 = const boost::system::system_error&]'
template<class U> R operator()(U const & u, A1 a1) const
^~~~~~~~
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:176:25: note: template argument deduction/substitution failed:
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:319:35: note: cannot convert '(& a)->boost::_bi::rrlist1<const boost::system::error_code&>::operator[](boost::_bi::storage2<boost::_bi::value<pinmed::cClass*>, boost::arg<1> (*)()>::a2_)' (type 'const boost::system::error_code') to type 'const boost::system::system_error&'
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn.hpp:215,
from C:\Users\James\code\boost\boost_1_69_0/boost/mem_fn.hpp:22,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind/bind.hpp:26,
from C:\Users\James\code\boost\boost_1_69_0/boost/bind.hpp:22,
from C:\Users\James\code\test_timed\main.cpp:3:
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:184:7: note: candidate: 'R boost::_mfi::mf1<R, T, A1>::operator()(T&, A1) const [with R = void; T = pinmed::cClass; A1 = const boost::system::system_error&]'
R operator()(T & t, A1 a1) const
^~~~~~~~
C:\Users\James\code\boost\boost_1_69_0/boost/bind/mem_fn_template.hpp:184:7: note: no known conversion for argument 1 from 'pinmed::cClass*' to 'pinmed::cClass&'
Process terminated with status 1 (0 minute(s), 8 second(s))
1 error(s), 12 warning(s) (0 minute(s), 8 second(s))
What is the signature of handler of deadline_timer::async_wait method?
According to reference it is:
void handler(
const boost::system::error_code& error // Result of operation.
);
What is your signature?
void handler(
const boost::system::system_error& e)
{
std::cout << "done\n";
}
Change your handler to:
void handler(
const boost::system::error_code& e)
{
std::cout << "done\n";
}
Why does one variant assignment compile while the other does not? The template instances do not share any types and char could be converted to int, say. What is boost::variant trying to do, that it cannot do in the case of the first assignment and that it can do in the case of the second assignment? Error is below.
#include <string>
#include "boost/variant.hpp"
int main()
{
boost::variant<char> v1;
boost::variant<std::string, int, double> v2;
v1 = v2; // compile error
v2 = v1; // compiles fine
return 0;
}
In file included from /usr/include/boost/variant.hpp:17:0,
from v.cpp:3:
/usr/include/boost/variant/variant.hpp: In instantiation of 'int boost::variant<T0, TN>::convert_copy_into::internal_visit(T&, int) const [with T = const std::basic_string<char>; T0_ = char; TN = {}]':
/usr/include/boost/variant/detail/visitation_impl.hpp:113:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; typename Visitor::result_type = int; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:156:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int]'
/usr/include/boost/variant/detail/visitation_impl.hpp:237:5: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, double, boost::mpl::l_end> > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2245:13: required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T0_ = std::basic_string<char>; TN = {int, double}; typename Visitor::result_type = int]'
/usr/include/boost/variant/variant.hpp:2267:13: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/variant/variant.hpp:1581:13: required from 'void boost::variant<T0, TN>::convert_construct_variant(Variant&) [with Variant = const boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1628:42: required from 'void boost::variant<T0, TN>::convert_construct(const boost::variant<U0, UN ...>&, long int) [with U0 = std::basic_string<char>; UN = {int, double}; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1649:38: required from 'boost::variant<T0, TN>::variant(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2059:29: required from 'void boost::variant<T0, TN>::assign(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2099:19: required from 'boost::variant<T0, TN>& boost::variant<T0, TN>::operator=(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
v.cpp:10:6: required from here
/usr/include/boost/variant/variant.hpp:1366:61: error: no matching function for call to 'boost::variant<char>::initializer::initialize(void* const&, const std::basic_string<char>&)'
return initializer::initialize(storage_, operand);
^
/usr/include/boost/variant/variant.hpp:1366:61: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:32:0,
from /usr/include/boost/variant.hpp:17,
from v.cpp:3:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const char&]
static int initialize(void* dest, param_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param_T {aka const char&}'
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = char&&]
static int initialize(void* dest, param2_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param2_T {aka char&&}'
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
static void initialize();
^
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: candidate expects 0 arguments, 2 provided
A char definitely can be stored in an int but the converse is not always true. Therefore the one that fails to compile would be unsafe at runtime, so you're probably better off with it failing. Cast the int to a char if you must.
I'm have the following elements:
#define TEMPLATE_PARAM boost::variant<int, const std::string&, const std::vector<std::string>&, const std::vector<int>&, const ITemplateLoop*, const std::vector<ITemplateLoop*>&>
class PostParam
{
...
const std::string &getParam() const;
};
class ParamContainer
{
std::map<std::string, TEMPLATE_PARAM> map_;
template <typename T>
void insert(std::string key, const T & value)
{
map_[key] = value;
}
public:
template<typename ... Args>
void add(std::map<std::string, std::shared_ptr<PostParam>>& param, Args ... args)
{
for (const auto & key : param)
insert(key.first, key.second->getParam());
if (sizeof ...(Args) > 0)
add(args...);
}
I am getting a lot of compilation error and I don't know what to paste here
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::de tail::reference_content<const std::basic_string<char>&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::basic_string<char>&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor=boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::basic_string<char>&>, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&, const PostParam&>::has_fallback_type_, typename Visitor::result_type = void]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>, step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter< boost::mpl::l_item<mpl_::long_<7l>, int, boost::mpl::l_item<mpl_::long_<6l>, boost::detail::reference_content<const std::basic_string<char>&>, boost::mpl::l_item<mpl_: :long_<5l>, boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, boost::mpl::l_item<mpl_::long_<4l>, boost::detail::reference_content<const std::vector<int>&>, boost::mpl::l_item<mpl_::long_<3l>, const TemplateEngine::ITemplateLoop*, boost::mpl::l_item<mpl_::long_<2l>, boost::detail::reference_content<const std::vector<TemplateEngine::ITemplateLoop*>&>, boost::mpl::l_item<mpl_::long_<1l>, boost::detail::reference_content<const PostParam&>, boost::mpl::l_end> > > > > > > >, boost::mpl::l_iter<boost::mpl::l_end> >, Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&, const PostParam&>::has_fallback_type_, typename Visitor::result_type = void, mpl_::false_ = mpl_::bool_<false>]'
I think it's the parameter that I get using key.second->getParam() but I'm unable to find a solution
Edit
I have changed the #define to the typedef
So the error message
/home/django/cloaked-ninja/includes/TemplateEngine.hpp:67:7: instantiated from 'void TemplateEngine::ParamContainer::insert(std::string, const T&) [with T = std::basic_string<char>, std::string = std::basic_string<char>]'
/home/django/cloaked-ninja/includes/TemplateEngine.hpp:94:2: instantiated from 'void TemplateEngine::ParamContainer::add(std::map<std::basic_string<char>, std::shared_ptr<PostParam> >&, Args ...) [with Args = {}]'
/home/django/cloaked-ninja/src/Controller/ControllerPost.cpp:22:14: instantiated from here
/usr/local/include/boost/detail/reference_content.hpp:62:24: error: 'boost::detail::reference_content<RefT>& boost::detail::reference_content<RefT>::operator=(const boost::detail::reference_content<RefT>&) [with RefT = const std::basic_string<char>&, boost::detail::reference_content<RefT> = boost::detail::reference_content<const std::basic_string<char>&>]' is private
/usr/local/include/boost/variant/variant.hpp:583:9: error: within this context
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::de tail::reference_content<const std::vector<std::basic_string<char> >&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const
std::vector<std::basic_string<char> >&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&>::has_fallback_type_, typename Visitor::result_type = void]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>, step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<6l>, int, boost::mpl::l_item<mpl_::long_<5l>, boost::detail::reference_content<const std::basic_string<char>&>, boost::mpl::l_item<mpl_::long_<4l>, boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, boost::mpl::l_item<mpl_::long_<3l>, boost::detail::reference_content<const std::vector<int>&>, boost::mpl::l_item<mpl_::long_<2l>, const TemplateEngine::ITemplateLoop*, boost::mpl::l_item<mpl_::long_<1l>, boost::detail::reference_content<const std::vector<TemplateEngine::ITemplateLoop*>&>, boost::mpl::l_end> > > > > > >, boost::mpl::l_iter<boost::mpl::l_end> >, Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&>::has_fallback_type_, typename Visitor::result_type = void, mpl_::false_ = mpl_::bool_<false>]'
Edit2
I have just changed the #define to the following typedef and it's now working:
typedef boost::variant<int, const std::string*, const std::vector<std::string>*, const std::vector<int>*, const ITemplateLoop*, const std::vector<ITemplateLoop*>*> TEMPLATE_PARAM;
If I'm not completely mistaken, the problem lies within your variant declaration. boost::variant can not take values as const &, because a copy of the data is required.
Here is a minimal working example:
#include <boost/variant.hpp>
#include <string>
#include <map>
struct foo
{
typedef boost::variant<int, std::string> variant;
std::map<std::string, variant> map;
template <typename T>
void insert(std::string const & key, T const & value)
{
map[key] = value;
}
};
int main()
{
foo f;
f.insert("test", "foo");
return 0;
}
I have a series of vectors which I am adding into a DataFrame object to return to R.
The problem comes when I try and add a vector with long long elements.
// [[Rcpp::export]]
DataFrame test()
{
std::vector<long long> x;
return DataFrame::create(Named("x") = x);
}
The error returned is
g++ -m64 -I"C:/R/R-30~1.1/include" -DNDEBUG -I"C:/R/R-3.0.1/library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c quotes.cpp -o quotes.o In file included from C:/R/R-3.0.1/library/Rcpp/include/RcppCommon.h:117:0, from C:/R/R-3.0.1/library/Rcpp/include/Rcpp.h:27, from quotes.cpp:1: C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h: In function 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown_iterable(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]': C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:691:98: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:723:96: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:740:80: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown_importable(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:760:99: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_unknown_tag) [with T = long long int, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:863:104: instantiated from 'SEXPREC* Rcpp::wrap(const T&) [with T = long long int, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:193:3: [ skipping 14 instantiation contexts ] C:/R/R-3.0.1/library/Rcpp/include/Rcpp/vector/Vector.h:395:9: instantiated from 'static void Rcpp::Vector::replace_element__dispatch(Rcpp::traits::true_type, Rcpp::Vector::iterator, SEXP, int, const U&) [with U = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::traits::true_type = Rcpp::traits::integral_constant, Rcpp::Vector::iterator = Rcpp::internal::Proxy_Iterator >, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/vector/Vector.h:384:9: instantiated from 'static void Rcpp::Vector::replace_element(Rcpp::Vector::iterator, SEXP, int, const U&) [with U = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector::iterator = Rcpp::internal::Proxy_Iterator >, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/Vector_create.h:318:2: instantiated from 'static Rcpp::Vector Rcpp::Vector::create_dispatch(Rcpp::traits::true_type, const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector = Rcpp::Vector<19>, Rcpp::traits::true_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/Vector__create.h:288:37: instantiated from 'static Rcpp::Vector Rcpp::Vector::create(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector = Rcpp::Vector<19>]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/DataFrame_generated.h:59:73: instantiated from 'static Rcpp::DataFrame Rcpp::DataFrame::create(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, Rcpp::DataFrame = Rcpp::DataFrame]' quotes.cpp:58:26: instantiated from here C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:474:11: error: invalid conversion from 'long long int' to 'SEXP' [-fpermissive] make: * [quotes.o] Error 1 .
Is there a way to add a vector of this type into a DataFrame?
There is not, sadly, as CRAN only allows a C standard without long long.
Also, R itself only has numeric (aka double) and integer. So I would suggest you just use double as a type.