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?
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)
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.
Related
Comment: I'm posting this question again, since some people requested me to post the full code. Here it is:
I have a function pointer typedef that looks like this:
template<typename USER_DATA>
class RowProcessor
{
typedef void (*RowFunction)(USER_DATA, std::vector<USER_DATA> &);
RowProcessor(RowFunction, int) {};
};
and then I'm using in another class UseRowProcessor:
class UseRowProcessor {
public:
void AddUserData(SomeClass, std::vector<SomeClass> &);
void LoadUserData();
};
void UseRowProcessor::AddUserData(SomeClass c, std::vector<SomeClass> &v) {
v.push_back(c);
}
void UseRowProcessor::LoadUserData() {
RowProcessor<SomeClass> myRowProcessor(AddUserData, 1); // ERROR!!
}
So the error occurs when calling RowProcessor's constructor.
The full error message says that
no insatnce of constructor "RowProcessor<USER_DATA>::RowProcessor [with USER_DATA=SomeClass]" matches the argument list
argument types are: (void (SomeClass c, std::vector<SomeClass, std::allocator<SomeClass>> &v), std::vector<SomeClass, std::allocator<SomeClass>>)
, which I have no idea what it says except for the fact that the constructor arguments do not match..
Why doesn't my AddUserFunction match the function pointer typedef??
TEST LINK<<<<<<<<
Change the function:
void AddUserData(SomeClass, std::vector<SomeClass> &);
to static void AddUserData(SomeClass, std::vector<SomeClass> &); .
As it is a class member function, the this parameter will be added after compiler, so it is not the type of the function pointer. By changing it to static, no this parameter will be added.
As Matt said you need a static function to get this working
class UseRowProcessor {
public:
static void AddUserData(SomeClass, std::vector<SomeClass> &);
void LoadUserData();
};
Here's the completely fixed sample (there were some more issues after fixing to static).
Member functions are different from ordinary functions and this carries over to their type. There is a set of work-arounds that enable you to pass member function pointers to functions that take ordinary function pointers as their parameters, but if you have control over the code you should take a different path. Instead of accepting a function pointer accept a functor.
template<typename Functor>
int f(Functor func) {
// use func like you would a function, e.g. call it with arguments func(1, 2)
}
Now you can call f with a lambda, function object, member function pointer (after you bound it to this), or function pointer.
If you want to avoid templates, accept a std::function instead, but this should only be done if you have special reasons for it.
I am working with a template class which parses data. Each line of data will require calling one of two functions to handle the data. This decision is determined at the time the parser is constructed and depends on variables passed to the constructor. I thought it would be useful to use a function pointer for this so that i could use one if statement in the constructor and assign the proper function to the function pointer which will be used in the body of the program. I am getting an error which I cannot figure out and I am curious if I am using the function pointer correctly in this context.
template<class T1, class T2>
class MyClass{
protected:
void (*pDoSomething)(std::string,std::string,std::string);
void functionOne(std::string,std::string,std::string);
void functionTwo(std::string,std::string,std::string);
public:
MyClass(bool option);
void parseData();
};
templace<class T1, class T2>
MyClass<T1,T2,>::MyClass(bool option){
if (option) pDoSomething = &functionOne;
else pDoSomething = &functionTwo;
}
template<class T1, class T2>
void MyClass<T1,T2>::parseData(){
/* . . . */
while(dataToParse){
*pDoSomething(string1, string2, string3);
}
/* . . . */
}
Change it like so:
template<class T1, class T2>
class MyClass
{
typedef void (MyClass::*ptmf)(std::string, std::string, std::string);
ptmf the_function;
explicit MyClass(bool b)
: the_function(b ? &MyClass::functionOne : &MyClass::functionTwo)
{ }
void parse_data()
{
(this->*the_function)(s1, s2, s3);
}
// ...
};
The error is most likely from the use of the function pointer to point to member functions. There is a considerable difference between functions that are in classes and just normal functions. You are assigning a class function to a normal function pointer. The difference comes in when you consider that all member functions take a hidden this pointer as their first argument.
Either change the functions to be outside of the class (or instead use static functions if the functions do not need any of the class's variables, bases or the this pointer) or change the function pointer to a class member function pointer. A pointer to a MyClass function that takes a string will look like this.
void (MyClass::*fptr)(std::string str);
Because the class function pointer requires a hidden this pointer the call of the function pointer changes also. To call the function pointed to by fptr you can use the ->* or .* c++ operators. So to call it using the this pointer of MyClass you can do this:
std::string aString;
(this->*fptr)(aString);
I'm not entirely sure but it maybe possible to do what you hope to do with virtual functions instead? This can be achieved by having two separate classes and a pointer to an instance of one of the two. Both classes derive from a class that has a pure virtual function that is the same as the function you are assigning here. This is a cleaner solution than using function pointers. I would look into this as you may find it useful if your looking for dynamic behavior using function pointers.
This is a good tutorial on the basics of function pointers:
http://www.learncpp.com/cpp-tutorial/78-function-pointers/
Basically, I have a templated class that runs some algorithm, and that algorithm needs a similarity(T t1, T t2) function that returns a double defining how similar two objects of type T are. This similarity function varies greatly depending on what T is defined as, so the caller of this class needs to define the similarity function. I assume a function pointer is in order, but how do I save a function from a function pointer as a member function for use in the algorithm?
That is, I want to pass in similarity(T t1, T t2) in the class' constructor and be able to call that as a member function throughout the class. How do I do that? Thanks
You can't add member functions to a class at runtime.
You could write a member function that calls the supplied function via the function pointer:
class MyClass {
typedef double (*similarity_fn_type)(T t1, T t2);
similarity_fn_type similarity_fn;
public:
MyClass(similarity_fn_type ptr) : similarity_fn(ptr) {}
double similarity(T t1, T t2) {
return similarity_fn(t1, t2);
}
};
Alternatively, you could make the similarity_fn member public. The syntax for calling it would make it look like a member function, but you might not consider it to be great encapsulation.
There are cleaner, object-oriented ways to do that. One of them is to pass an object with that function, similar to how Java allows reimplementing comparisons with the Comparator class. This implies the creation of a base class (with that function as purely virtual) and a subclass for each implementation of similarity().
In your case, you may find more useful the solution C++11 takes for implementing functions for comparing and hashing. It involves creating special function objects. See std::less and std::hash for examples.
I do something similar to abstract away the process of iterating through a collection. I use a predicate to specify the actual search criteria:
void MyClass::Copy(Class &destination, const Class &source, const std::function<bool (const Effect&)> &predicate)
{
for (size_t i = 0; i < Effect::Max; ++i)
{
const Effect *const pEffect = source.GetEffect(i);
if (predicate(*pEffect))
{
// Do something
}
}
}
void MyClass::CopyInner(Class &destination, const Class &source)
{
this->Copy(destination, source, [](const Effect &effect)
{
return effect.IsInner();
});
}
Note: This uses some C++11 features.
Define a const function pointer member of the appropriate type:
typedef double(*Similarity)(T, T);
const Similarity similarity;
Let the constructor accept a function of that type:
Class(Similarity f) : similarity(f) {}
Then calling the function has the same syntax as calling an ordinary member function:
frobnicate(similarity(foo, bar));
And if the member is public, it cannot be changed out from under you because it’s const.
I'm using a 3rd party library that allows me to register callbacks for certain events. The register function looks something like this. It uses the Callback signature.
typedef int (*Callback)(std::string);
void registerCallback(Callback pCallback) {
//it gets registered
}
My problem is that I want to register a member function as a callback something like this
struct MyStruct {
MyStruct();
int myCallback(std::string str);
};
MyStruct::MyStruct() {
registerCallback(&MyStruct::myCallback);
}
int MyStruct::myCallback(std::string str) {
return 0;
}
Of course, the compiler complains, saying
error C2664: 'registerCallback' : cannot convert parameter 1 from 'int (__thiscall MyStruct::* )(std::string)' to 'Callback'
I've been looking at boost libraries like function and bind, but none of those seem to be able to do the trick. I've been searching all over Google for the answer, but I don't even know what to call this, so it hasn't been much help.
Thanks in advance.
You're trying to pass a member function pointer as a normal function pointer which won't work. Member functions have to have the this pointer as one of the hidden parameters, which isn't the case for normal functions, so their types are incompatible.
You can:
Change the type of your argument to accept member functions and also accept an instance to be the invoking object
Quit trying to pass a member function and pass a normal function (perhaps by making the function static)
Have a normal function that takes an instance of your class, a member function pointer, and a std::string and use something like boost's bind to bind the first two arguments
Make the callback registration function accept a functor object, or an std::function (I think that's the name)
Numerous other ways which I won't detail here, but you get the drift.
Member functions are not convertible to the normal functions for its own good reasons. If your design allows, then make MyStruct::myCallback() a static member method and the code should work fine.
struct MyStruct {
...
static int myCallback(std::string str);
^^^^^^
};
Due to the inflexible hardcoding of an actual function type for the callback you can't use any of the normal adapting or binding tricks to help you here. The third party library really wants you to pass in a non-member function and there isn't much you can do. You may want to consider why you're trying to pass it the address of a member function, and if your design or use of the library could change.
One option, if you only need to set a single callback, is to have a static or namespace private function that refers to a singleton instance pointer, and uses that to dispatch upon callback.
If you need multiple items, then possibly a template would wrap the hackiness (untested code here, just the idea).
template <int which_callback>
struct CallbackHolderHack
{
static int callback_func(std::string str) { dispatchee_->myCallback(str); }
static MyStruct* dispatchee_;
};
template <int which_callback>
MyStruct* CallbackHolderHack::dispatchee_(0);
And use it:
CallbackHolderHack<0>::dispatchee_ = new MyStruct;
registerCallback(&CallbackHolderHack<0>::callback_func);
Depends on how you are using it.... eg a Singlton would be much simplier
struct MyStruct {
static MyStruct& Create() {
static MyStruct m; return m;
}
static int StaticCallBack(std::string str) {
return Create().Callback(str)
}
private:
int CallBack(std::string str);
MyStruct();
};
Or if you want to have many of these objects you have several choices. You would need a way to route it before the callback is called.
Since you are using C++, why not make the callback a functor object? Then you can use std::mem_fun.
Edit: Seems std::mem_fun has been deprecated in the latest C++11 standard. So std::function might be a better solution if you have a new compiler.
See this SO question for hints about using it.
class ICallBackInterface
{
public:
virtual void FireCallBack( std::string& str ) = 0;
};
std::set<ICallBackInterface*> CallBackMgr;
class MyStruct : public ICallBackInterface
{
public:
MyStruct()
{
CallBackMgr.insert( this );
}
~MyStruct()
{
CallBackMgr.erase( this );
}
virtual void FireCallBack( std::string& str )
{
std::cout << "MyStruct called\n";
}
};
void FireAllCallBack(std::string& str )
{
for ( std::set<ICallBackInterface*>::iterator iter = CallBackMgr.begin();
iter != CallBackMgr.end();
++iter)
{
(*iter)->FireCallBack( str );
}
}
This is another way to use polymorphism to achieve the same effect
I have a std::map which I'm trying to store void pointers for the values. The problem is, most of the pointer I'm trying to store are methods in a class and have different amount of params. I know for the params I can use a va list so thats not too much of a problem, the problem would be the actual pointer itself.
This is what I have:
class A
{
public:
A();
void methodA(...);
};
class B
{
public:
B();
void methodB(...);
};
void method_no_class(...) { }
std::map<int, void(*)(...)> my_map;
my_map[0] = &method_no_class;
B* cb = new B();
my_map[1] = &cb->methodB; // will return error
Maybe this information my help you:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
Pointer to method is of different type than pointer to function. If you want to store them both in single collection you have to do manual casts.
The clean OO way would be to define a command interface. The interface would take an instance (of A or B) and all parameters. In the invoke() method, it would call the method of the instance.
You could then use a map of these command interfaces (just define a common subclass for them which defines the abstract invoke() method). The compiler would check all types and arguments for you, and you wouldn't have to use varargs.
Following up on Kamil Szot's answer, the C++ FAQ (and the book) is an excellent reference to the murky depths of C++ and object oriented programming in general. Section 33 addresses specifically the problem you are having:
In C++, member functions have an implicit parameter which points to the object (the this pointer inside the member function). Normal C functions can be thought of as having a different calling convention from member functions, so the types of their pointers (pointer-to-member-function vs. pointer-to-function) are different and incompatible.
Of course, the answer to your question is somewhat lacking in details.
You might want to look at method operaters ->, ::, and their friends. I'll try to find a better link but start here.
UPDATE: hopefully this is a better article for method pointers and operators.
You should functionoids here. They can be used as a flexible and type safe replacement for function pointers with different signatures. A abstract base class is needed. It contains the actual function invocation with the common parameters, if there are any.
class Functioniod: public YourClass {
virtual void execute(char d, common_parameters,...) = 0
}
For every function you want to use, you create a derived class. The constructor contains the function-specific parameters, and the execute() function the actual call. This execute function is later called instead of the function pointer. It needs to have the same signature in every functionoid. It could call something different in any other class too, of course.
class FuncA: public Functionoid {
FuncA(int _a, float _b, string _c, function-specific-parameters...) {
a = _a; b = _b; c = _c;
}
void execute(char d, common-parameters,...) {
call-to-member(d, a, b, c);
}
int a;
float b;
string c;
}
Now if you want to use this as a replacement for your member function pointer, you would do:
std::map<int, *Functionoid> my_map;
my_map[0] = new FuncA(someInt, someFloat, someString);
my_map[1] = new FuncB(some-other-parameters...);
and execute them with
my_map[0]->execute(common-parm);
my_map[1]->execute(common-parm);
Here's an example code to get you started. Haven't compiled it, so might require some tuning.
#define func(Instance,Method,Class) \
(__int64(Instance)<<32 + __int64(&Class::Method))
#define invoke(Func,Method,Class) \
invoke1(Func,(Class*)0)->*invoke2(Func,&Class::Method)
template<class Class>
Class* invoke1(__int64 Func,Class*)
{
return (Class*)(int)(Func>>32);
}
template<class Method>
Method invoke2(__int64 Func,Method)
{
return (Method)(int)Func;
}
------------ USAGE ------------
class B
{
void methodB(int a,float b){}
};
std::map<int, __int64> my_map;
my_map[0] = func(cb,methodB,B);
invoke(my_map[0],methodB,B)(1,2.f);