【发布时间】:2015-02-20 05:37:33
【问题描述】:
我今天对 boost::asio 项目进行了一些修改,在尝试将绑定函数传递给异步调用时遇到了令人困惑的编译错误。
我花了几个小时摆弄这段代码,所以我怀疑我错过了一些愚蠢的东西。谁能指出我哪里出错了,我将不胜感激。
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&)’
注意到const MCServer& 出现了两次?我的绑定语句不是这样写的:
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
)
);
}
在Connection header中statusPing(...)定义如下:
void statusPing(boost::function<
void(
MCServer&, boost::shared_ptr<Connection>,
const boost::system::error_code&
)>);
最终要调用的处理程序:
void ClientServerManager::onPingCompletion(
const MCServer& server_info,
boost::shared_ptr<Connection>,
const boost::system::error_code& err){
// Use the results to drive some function...
}
背景:
- 我有一个类遍历服务器列表并打开 与他们建立短暂的联系,以确保他们正在运作 适当地。
- 该类使用一个实用程序,
Connection,它继承boost::enable_shared_from_this.因此,我调用一个函数Connection::create(..)来获取boost::shared_ptr开始工作。当进行任何异步调用时,必须传递此指针以将连接保持在范围内。 - 在这种情况下,成功建立连接后,我想将执行传递给
Connection,以便它可以执行一些任务,并且我希望它在这些任务完成后调用句柄。 在这种情况下,我无法让 boost::bind 正确编译。 - 现在我遇到的问题是
boost::bind可能与boost::asio::placeholders::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::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&’
编辑:(boost::function<void(...)> -> boost::function<void()>)
根据建议,我将Connection 函数更改为读取void statusPing(boost::function<void()>);,因为绑定了参数。此更改会产生不同的错误:
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
一个简化的例子:
#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
)
);
}
【问题讨论】:
-
您正在绑定调用
ClientServerManager::onPingCompletion()所需的所有参数,因此从绑定表达式创建的可调用对象将转换为boost::function<void()>。尝试对statusPing()进行更改,您的代码应该可以编译。 -
另外,这些都是编译器错误,而不是链接器错误。您的问题一开始有点令人困惑,因为您一直提到链接和链接错误。
-
感谢@Praetorian 的指导。我仍然收到错误消息;你有什么额外的建议吗?
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>]’ -
你能显示更新的代码吗?请注意,
statusPing必须接受function<void()>,或者您应该创建一个接受 3 个参数的绑定器,例如bind(this, _1, _2, _3)- 取决于您实际打算如何调用该函子。 -
是导致新错误的同一行吗?您能否尝试创建一个重现该问题的SSCCE?
标签: c++ boost boost-asio