mem_func and virtual function
-
12-10-2019 - |
Question
I have the following classes:
class A
{
public:
virtual void myfunc(unsigned char c, std::string* dest) = 0;
};
class B : public class A
{
public:
virtual void myfunc(unsigned char c, std::string* dest);
};
void someOtherFunc(const std::string& str,A *pointerFunc)
{
std::string tmp;
for_each(str.begin(),
str.end(),
std::bind2nd(std::mem_fun(pointerFunc->myfunc), &tmp));
}
I get the following compilation error: error: no matching function for call to \u2018mem_fun()\u2019
Do you know why?
Solution
You're looking for std::mem_fun(&A::myfunc)
.
EDIT: You can't use mem_fun
at all here -- no overload of mem_fun
allows you to make a two argument member function into a functor. You're going to have to use something like boost::bind
/std::tr1::bind
(If you have TR1)/std::bind
(If you have C++0x) or you're going to have to write your own functor.
Note that even if mem_fun
was able to do this sort of binding, then std::bind2nd
would fail, because bind2nd
expects a functor taking two arguments, and binding a member function pointer like this is going to produce a functor with three arguments.
You have a few ways around this:
- Write your own functor that does what you want.
- Write an explicit loop instead of
std::for_each
. - One of the not-yet-standard binder functions I mentioned above (and demonstrated in @David's answer)
- Don't bother with the virtual function in the first place -- make your method accept a plain function pointer and implement things in terms of the function pointer. Of course this only works if
myfunc
doesn't depend on members of the class to which it belongs (in which case it shouldn't have ever been put into a class in the first place)
OTHER TIPS
What you are trying to use here is use a pointer to a member function to apply a member function of another object to every object in the container. Apparently none of the adapters will work in this case. In that case the only solution is to write a special wrapper functor class for it.
Looking at the implementation behind of std::mem_fun you should be able to write your own:
EDIT (made it "human-readable")
template<class Result, class Ty, class Arg>
class mem_fun1_t : public binary_function<Ty*, Arg, Result>
{
private:
Result (Ty::*m_mf)(Arg);
public:
mem_fun1_t(Result (Ty::*mf)(Arg)) : m_mf(mf) { }
Result operator()(Ty* pLeft, Arg Right) const {
return ((pLleft->*m_mf)(Right));
}
};
Your declaration does not represent what you want to do.
try:
void someOtherFunc(const std::string& str)
{
std::string tmp;
B BInstance;
A* ptrToB = &BInstance;
for_each(str.begin(),
str.end(),
boost::bind(&A::myfunc, ptrToB, _1, &tmp));
}
this (or a variation of) should do what you want.