referencing a member function with bind1st and mem_fun
I have a C++ class where I'm trying to use std::bind1st to bind a member function to the 'this' parameter. For example:
class MyClass
{
public:
void Foo()
{
using namespace std;
// this works fine
this->Bar();
// this also works fine
mem_fun( &MyClass::Bar )( this );
// this does not
bind1st( mem_fun( &MyClass::Bar ), this )();
// this is not a possibility for this program
boost::bind( &MyClass::Bar, this )();
};
void Bar()
{
};
};
When I add that last 'bind1st' line, I get the following compiler errors:
1>stl/_function.h(189) : error C2039: 'second_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1> with
1> [
1> _Ret=void,
1> _Tp=MyClass
1> ]
1> .\MyClass.cpp(50) : see reference to class template instantiation 'stlp_std::binder1st<_Operation>' being compiled
1> with
1> [
1> _Operation=stlp_std::mem_fun_t<void,MyClass>
1> ]
1>stl/_func开发者_运维技巧tion.h(189) : error C2146: syntax error : missing ',' before identifier 'second_argument_type'
1>stl/_function.h(189) : error C2065: 'second_argument_type' : undeclared identifier
1>stl/_function.h(190) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1> stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(191) : error C2039: 'second_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1> with
1> [
1> _Ret=void,
1> _Tp=MyClass
1> ]
1>stl/_function.h(191) : error C2146: syntax error : missing ',' before identifier 'second_argument_type'
1>stl/_function.h(191) : error C2065: 'second_argument_type' : undeclared identifier
1>stl/_function.h(194) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1> stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(195) : error C2955: 'stlp_std::unary_function' : use of class template requires template argument list
1> stl/_function_base.h(40) : see declaration of 'stlp_std::unary_function'
1>stl/_function.h(197) : error C2146: syntax error : missing ';' before identifier '_ArgParamType'
1>stl/_function.h(197) : error C3254: 'stlp_std::binder1st<_Operation>' : class contains explicit override 'param_type' but does not derive from an interface that contains the function declaration
1> with
1> [
1> _Operation=stlp_std::mem_fun_t<void,MyClass>
1> ]
1>stl/_function.h(197) : error C2838: 'param_type' : illegal qualified name in member declaration
1>stl/_function.h(197) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(197) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(198) : error C2146: syntax error : missing ';' before identifier '_ConstArgParamType'
1>stl/_function.h(198) : error C3254: 'stlp_std::binder1st<_Operation>' : class contains explicit override 'const_param_type' but does not derive from an interface that contains the function declaration
1> with
1> [
1> _Operation=stlp_std::mem_fun_t<void,MyClass>
1> ]
1>stl/_function.h(198) : error C2838: 'const_param_type' : illegal qualified name in member declaration
1>stl/_function.h(198) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(198) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(199) : error C2039: 'first_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1> with
1> [
1> _Ret=void,
1> _Tp=MyClass
1> ]
1>stl/_function.h(199) : error C2146: syntax error : missing ',' before identifier 'first_argument_type'
1>stl/_function.h(199) : error C2065: 'first_argument_type' : undeclared identifier
1>stl/_function.h(199) : error C2955: 'stlp_std::__call_traits' : use of class template requires template argument list
1> stl/type_traits.h(452) : see declaration of 'stlp_std::__call_traits'
1>stl/_function.h(203) : error C2039: 'first_argument_type' : is not a member of 'stlp_std::mem_fun_t<_Ret,_Tp>'
1> with
1> [
1> _Ret=void,
1> _Tp=MyClass
1> ]
1>stl/_function.h(203) : error C2146: syntax error : missing ';' before identifier '_M_value'
1>stl/_function.h(203) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(203) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>stl/_function.h(208) : error C2061: syntax error : identifier '_ConstArgParamType'
1>stl/_function.h(211) : error C2061: syntax error : identifier '_ArgParamType'
1>stl/_function.h(212) : error C2535: '_Result stlp_std::binder1st<_Operation>::operator ()(void) const' : member function already defined or declared
1> with
1> [
1> _Operation=stlp_std::mem_fun_t<void,MyClass>
1> ]
1> stl/_function.h(208) : see declaration of 'stlp_std::binder1st<_Operation>::operator ()'
1> with
1> [
1> _Operation=stlp_std::mem_fun_t<void,MyClass>
1> ]
I am using STLPort v5.2.1 for a standard library implementation.
Ordinarily, I would switch to boost::bind and use that. Unfortunately, that is not a possibility for this application.
What can I do to get the functionality I'm looking for?
Thanks, PaulH
Edit:
To be more clear, I'm looking for a way to adapt a unary function to whatever you call a function that takes no parameters. I want to 'bind' this
to MyClass::Bar
.
class SomeOtherClass
{
public:
template< typename Fcn >
void ExecuteFcn( Fcn fcn )
{
fcn();
};
};
some_other_class.ExecuteFcn( bind1st( mem_fun( &MyClass::Bar ), this );
What are you trying to accomplish with bind1st?
The bind1st
function takes a binary function and adapts it to a unary function by making the first argument implicit (this may not be the best description, sorry). The return value of mem_fun
is a unary function.
The mem_fun
function returns an adaptor for a member function. The adapted function doesn't take any arguments, though the adaptor returned takes one argument, a pointer to the MyClass object to be used.
So, basically, your mem_fun
call is returning a adaptor that takes one argument, but bind1st
is expecting an adaptor that takes two arguments. There is a mem_fun1
which returns an adaptor that takes two arguments, the first being the object pointer and the second being an argument for the function, but that isn't what you want here.
In fact, I don't quite understand what you're trying to do; why is the plain mem_fun
version not suitable? If you need the object pointer to be 'attached' to the adaptor, I don't think you can do that with the current standard library, unless you use bind.
Of course, you could make a wrapper class that holds the object pointer, and then just define operator() to call the adaptor with that object.
// Quick and dirty example of this.
// You could extend this with a second template parameter for return type, if
// needed. Just be sure to specialize for void if you do that.
template<typename Object>
struct bound_mem_fun_t {
bound_mem_fun_t(mem_fun_t<void, Object> f, Object* o) : fun(f), obj(o) { }
void operator()() { fun(obj); }
mem_fun_t<void, Object> fun;
Object* obj;
};
MyClass a;
bound_mem_fun_t<MyClass> func(mem_fun(&MyClass::Bar), &a);
func();
bind1st
requires a binary function, and returns an unary functor. Here, you pass an unary function.
The purpose of "binding" is to use a binary function/functor (like a non-static method with one parameter is) like an unary one, by setting one of its parameters to a given value.
This would work (note the new prototype of Bar
):
class MyClass
{
public:
void Foo()
{
using namespace std;
// this works fine
bind1st( mem_fun( &MyClass::Bar ), this )(42);
};
void Bar(int i)
{
};
};
I wanted to add one other possible solution to this, and that's using lambda functions from C++11.
Here's a quick example:
class MyClass
{
std::string mName;
public:
MyClass(const char* name) : mName(name) {};
void Foo()
{
std::cout << "My name is " << mName << std::endl;
};
};
void CallMyFn(std::function<void()> fn)
{
fn();
}
int main()
{
MyClass myInstance("Ishmael");
CallMyFn( [&]() { myInstance.Foo(); } );
return 0;
}
Output: "My name is Ishmael."
I believe it's not working because bind1st()
requires a binary function object and returns a unary function object. Since Bar()
takes no arguments, mem_fun()
is giving you a unary function object. bind1st()
doesn't know what to do with that.
How do you actually intend to use the function object produced by mem_fun()
?
精彩评论