使用clang++ -std=c++0x -stdlib=libc++ main.cpp
构建
#include <string>
#include <functional>
using std::bind;
using std::string;
using std::function;
class Service
{
public:
void listen( const function< void ( const string&, const string&, const string&, const string& ) > const& login )
{
}
};
class Threadpool
{
public:
void schedule( const function< void ( void ) > const& task )
{
}
};
class Server
{
public:
Server( )
{
Threadpool* threadpool = new Threadpool( );
Service* service = new Service( );
threadpool->schedule( bind( &Service::listen, service, mem_fn( &Server::subscribe ) ) );
}
void subscribe( const string& username, const string& password, const string& hostname, const string& data )
{
}
};
int main ( int argc, char** argv )
{
Server server( );
}
错误:
In file included from main.cpp:3:
/usr/include/c++/v1/functional:892:22: error: no matching function for call to '__invoke'
return __invoke(__f_, _STD::forward<_ArgTypes>(__args)...);
^~~~~~~~
/usr/include/c++/v1/__functional_base:437:12: note: in instantiation of function template specialization 'std::__1::__mem_fn<void
(Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &)>::operator()<const std::__1::basic_string<char> &, const std::__1::basic_string<char>
&, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>' requested here
return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
^
/usr/include/c++/v1/__config:153:14: note: instantiated from:
#define _STD std::_LIBCPP_NAMESPACE
^
/usr/include/c++/v1/functional:1054:12: note: in instantiation of function template specialization
'std::__1::__invoke<std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &>' requested here
return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
^
/usr/include/c++/v1/functional:1256:26: note: in instantiation of member function
'std::__1::__function::__func<std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)>,
std::__1::allocator<std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> >, void (const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &)>::operator()' requested here
::new (__f_) _FF(_STD::move(__f));
^
/usr/include/c++/v1/__functional_base:349:47: note: in instantiation of function template specialization 'std::__1::function<void
(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &)>::function<std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> >' requested
here
return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
^
/usr/include/c++/v1/__config:153:14: note: instantiated from:
#define _STD std::_LIBCPP_NAMESPACE
^
/usr/include/c++/v1/functional:1652:12: note: in instantiation of function template specialization 'std::__1::__invoke<void,
Service, Service *&, const std::__1::function<void (const std::__1::basic_string<char> &, const std::__1::basic_string<char>
&, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &, std::__1::__mem_fn<void (Server::*)(const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &)> &>' requested here
return __invoke(__f, __mu(get<_Indx>(__bound_args), __args)...);
^
/usr/include/c++/v1/functional:1681:20: note: in instantiation of function template specialization 'std::__1::__apply_functor<void
(Service::*)(const std::__1::function<void (const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &), std::__1::tuple<Service *, std::__1::__mem_fn<void
(Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &)> >, 0, 1, std::__1::tuple<> >' requested here
return __apply_functor(__f_, __bound_args_, __indices(),
^
/usr/include/c++/v1/__functional_base:437:12: note: in instantiation of function template specialization 'std::__1::__bind<void
(Service::*)(const std::__1::function<void (const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &), Service *, std::__1::__mem_fn<void
(Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &)> >::operator()<>' requested here
return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
^
/usr/include/c++/v1/__config:153:14: note: instantiated from:
#define _STD std::_LIBCPP_NAMESPACE
^
/usr/include/c++/v1/functional:1054:12: note: in instantiation of function template specialization
'std::__1::__invoke<std::__1::__bind<void (Service::*)(const std::__1::function<void (const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &),
Service *, std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> > &, >' requested here
return __invoke(__f_.first(), _STD::forward<_ArgTypes>(__arg)...);
^
/usr/include/c++/v1/functional:1256:26: note: in instantiation of member function
'std::__1::__function::__func<std::__1::__bind<void (Service::*)(const std::__1::function<void (const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &)> &), Service *, std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> >,
std::__1::allocator<std::__1::__bind<void (Service::*)(const std::__1::function<void (const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &),
Service *, std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> > >, void ()>::operator()' requested here
::new (__f_) _FF(_STD::move(__f));
^
main.cpp:36:31: note: in instantiation of function template specialization 'std::__1::function<void
()>::function<std::__1::__bind<void (Service::*)(const std::__1::function<void (const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> &), Service *,
std::__1::__mem_fn<void (Server::*)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &)> > >' requested here
threadpool->schedule( bind( &Service::listen, service, mem_fn( &Server::subscribe ) ) );
^
/usr/include/c++/v1/__functional_base:293:1: note: candidate template ignored: substitution failure [with _R = void, _T = Server,
_T1 = const std::__1::basic_string<char> &, _Param = <const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>, _Arg = <const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>]
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:306:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:319:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:332:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:347:1: note: candidate template ignored: substitution failure [with _R = void, _T = Server,
_T1 = const std::__1::basic_string<char> &, _Param = <const std::__1::basic_string<char> &, const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>, _Arg = <const
std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>]
__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:360:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:373:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:386:1: note: candidate template ignored: failed template argument deduction
__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
^
/usr/include/c++/v1/__functional_base:400:1: note: candidate function template not viable: requires 2 arguments, but 5 were
provided
__invoke(_R _T::* __f, _T1&& __t1)
^
/usr/include/c++/v1/__functional_base:425:1: note: candidate function template not viable: requires 2 arguments, but 5 were
provided
__invoke(_R _T::* __f, _T1&& __t1)
^
/usr/include/c++/v1/__functional_base:435:1: note: candidate template ignored: substitution failure [with _F = void
(Server::*&)(const std::__1::basic_string<char> &, const std::__1::basic_string<char> &, const std::__1::basic_string<char>
&, const std::__1::basic_string<char> &), _T = <const std::__1::basic_string<char> &, const std::__1::basic_string<char> &,
const std::__1::basic_string<char> &, const std::__1::basic_string<char> &>]
__invoke(_F&& __f, _T&& ...__t)
^
1 error generated.
答案 0 :(得分:3)
作业?如果是这样,我会获得一些荣誉。 : - )
我看到你刚刚在我研究你的问题时纠正了你的第一个错误,所以我会跳过那个。
下一步:
&Service::listen
期待function<void(string, string, string, string)>
。您需要将其中一个明确传递到bind
。
bind( &Service::listen, service, function< void ( const string&, const string&,
const string&, const string& ) >
(something goes here) )
我会再次使用bind
作为第二部分,但您需要表明,除了Server*
之外,这个辅助仿函数还需要4个参数。这些参数是4个字符串,尚不可用。您可以为这些字符串传入“占位符”。这可以通过以下方式完成:
using namespace std::placeholders;
threadpool->schedule(
bind( &Service::listen, service,
function< void ( const string&, const string&,
const string&, const string& ) >(
bind( &Server::subscribe, this, _1, _2, _3, _4 ) ) ) );
将所有内容放在一起,并加入一些打印声明进行确认:
#include <string>
#include <functional>
#include <iostream>
using std::bind;
using std::string;
using std::function;
class Service
{
public:
void listen( function< void ( const string&,
const string&,
const string&,
const string& ) > const& login )
{
std::cout << "in listen\n";
login("w", "x", "y", "z");
}
};
class Threadpool
{
public:
void schedule( const function< void ( void ) > const& task )
{
std::cout << "in schedule\n";
task();
}
};
class Server
{
public:
Server()
{
Threadpool* threadpool = new Threadpool( );
Service* service = new Service( );
using namespace std::placeholders;
threadpool->schedule(
bind( &Service::listen, service,
function< void ( const string&, const string&,
const string&, const string& ) >(
bind( &Server::subscribe, this, _1, _2, _3, _4 ) ) ) );
}
void subscribe( const string& username, const string& password,
const string& hostname, const string& data )
{
std::cout << "in subscribe\n";
std::cout << username << '\n';
std::cout << password << '\n';
std::cout << hostname << '\n';
std::cout << data << '\n';
}
};
int main ()
{
Server server;
}
我明白了:
in schedule
in listen
in subscribe
w
x
y
z
顺便说一下,这会泄漏内存。纠正这是留给读者的练习。 : - )
答案 1 :(得分:1)
为了完整起见,我的解决方案如下。
#include <string>
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::bind;
using std::string;
using std::function;
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;
using std::placeholders::_5;
class Service
{
public:
void listen( const function< void ( const string&, const string&, const string&, const string& ) > const& login )
{
login( "ben", "crowhurst", "localhost", "some data" );
}
};
class Threadpool
{
public:
Threadpool( ) { }
void schedule( const function< void ( ) > const& task )
{
cout << "in schedule" << endl;
task( );
}
};
class Server
{
public:
Server( )
{
Threadpool* threadpool = new Threadpool( );
Service* service = new Service( );
function<void (const string&, const string&, const string&, const string&)> f1 =
bind( &Server::subscribe, this, _1, _2, _3, _4 );
auto f2 = bind( &Service::listen, service, f1 );
threadpool->schedule( f2 );
}
void subscribe( const string& username, const string& password, const string& hostname, const string& data )
{
cout << "username: " << username << endl;
cout << "password: " << password << endl;
cout << "hostname: " << hostname << endl;
cout << " data: " << data << endl;
}
};
int main ( int argc, char** argv )
{
cout << "in main" << endl;
Server* server = new Server( );
}
答案 2 :(得分:0)
首先,typedef是你的朋友:
typedef std::function<void(void)> RequestFunc;
typedef std::function<void(const std::string&, const std::string&)> DispatchFunc;
我们现在可以按如下方式提出您的声明。我已将参数更改为deliver
以采用dispatchFunc(因为原始参数是一个无参数的void)。我还在类声明之后添加了;
,并且由于可访问性问题而使您尝试与public
绑定的函数:
class A {
std::string name;
std::string location;
public:
void deliver( const DispatchFunc& request )
{
request( name, location );
}
};
class B {
public:
void dispatch( const DispatchFunc& request )
{
};
};
其次,我怀疑您的deliver()
函数实际上需要DispatchFunc
typedef。在不知道您的代码段的目的的情况下,很难说出您想要绑定的类型。
现在已经对声明进行了排序。由于与Windows套接字库的命名冲突,使用bind
(在Windows中至少)存在问题。这可能是您的编译器上的问题,也可能不是问题,但在boost
名称空间前加上前缀总是一个好主意:
B b;
auto func1 = boost::bind( &B::dispatch, b );
A a;
auto func2 = boost::bind( &A::deliver, a, func1);
这些修改为我成功编译。至于其余的以及你打算做什么,祝你好运。