How to pair/multimap <int, pointer to a function>?
Could someone help with the correct syntax? I tried something like
Code:
class myclass {
multimap<int, void(*)()> mm_fn;
...
void afunction();
...
void anotherfunction(int anint){
mm_fn.insert(pair<int,void(*)()>(anint,afunction));
}
}
and the compiler does not like it. Thanks!
Re: How to pair/multimap <int, pointer to a function>?
C++ class methods are not compatible with C-style function pointers (at least, not without special syntax), because they have an additional hidden parameter "this".
I recommend you use std::function, which can handle a class method with the help of std::bind, instead of a function pointer if your compiler supports it. If not, boost::function and boost::bind have approximately equivalent behavior.
Another option is to make afunction() static, and add the object pointer ("this") as an explicit parameter if necessary. (If it isn't necessary, then perhaps afunction should have been static anyway.)
Re: How to pair/multimap <int, pointer to a function>?
Re: How to pair/multimap <int, pointer to a function>?
It's seldom the proper thing to do but you can always "bypass the type system". You see it in very low-level C-style code that has to be very general.
Code:
void afunction() {
std::cout << "hello" << std::endl;
}
std::unordered_multimap<int, void*> mm_fn;
//
int aint = 13;
mm_fn.insert(std::make_pair(aint, reinterpret_cast<void*>(&afunction)));
void(*foo)();
foo = reinterpret_cast<void(*)()>(mm_fn.find(aint)->second);
foo();
void* is a pointer to anything really (for example it's what malloc returns). You need to cast it to and back from the wanted type and for that you use reinterpret_cast.
Assuming this is for high performance purposes, unordered_multimap is faster than multimap. make_pair is for convenience.
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
nuzzle
It's seldom the proper thing to do but you can always "bypass the type system". You find it in very low-level C-style code that has to be very general.
http://www.parashift.com/c++-faq-lit...html#faq-33.10
http://www.parashift.com/c++-faq-lit...html#faq-33.11
Regards,
Paul McKenzie
Re: How to pair/multimap <int, pointer to a function>?
A more C++ way to approach what you want, that doesn't require you to bypass the type system, would be to store a map of pointers to function objects instead. The derived function objects classes can either implement the functionality or act as wrappers around other class methods or static functions.
Maybe this could be something like you are trying to implement.
Code:
#include <iostream>
#include <map>
#include <algorithm>
//**** Base ****
struct FunctionObject
{
virtual void operator ()() = 0;
};
//**** Function object ****
struct F1 : public FunctionObject
{
void operator ()()
{
std::cout << "F1 operator ()\n";
}
};
//**** Wrapper for class member function ****
struct SomeStruct
{
void MemberFunction()
{
std::cout << "Member Function\n";
}
} someStruct;
struct F2 : public FunctionObject
{
void operator ()()
{
someStruct.MemberFunction();
}
};
//**** Wrapper for static function ****
void SomeStaticFunction()
{
std::cout << "Some Static Function\n";
}
struct F3 : public FunctionObject
{
void operator ()()
{
SomeStaticFunction();
}
};
int main()
{
// The function objects.
F1 f1;
F2 f2;
F3 f3;
// The map.
std::map<int, FunctionObject*> mm_fn;
mm_fn[1] = &f1;
mm_fn[2] = &f2;
mm_fn[3] = &f3;
// Iterate and call.
std::map<int, FunctionObject*>::iterator itr = mm_fn.begin();
while (itr != mm_fn.end())
{
// Get the function object.
FunctionObject& functionObject = *itr->second;
// Call it.
functionObject();
++itr;
}
return 0;
}
Re: How to pair/multimap <int, pointer to a function>?
Thank you everyone! Following Lindley's suggestions I changed the code to
Code:
class myclass {
multimap<int, mem_fun_t<void, myclass > > mm_fn;
...
void afunction();
...
void anotherfunction(int anint){
mm_fn.insert(pair<int, mem_fun_t<void, myclass > >(anint, mem_fun(&myclass::afunction)));
}
}
Now the compiler does not complain but I am not sure if this is legal or will work as intended (please see paragraph below).
What I would like to do is to build a multimap at run time. In the beginning the program reads in a file telling it which integer points to which member function. One integer may point to one or more member functions. A multimap is built according to the file content. After that the program receives integer input and calls the corresponding member function(s) in the multimap. (I haven't got to this part - not sure if I am on the right track yet.)
Please help. Thanks!
Re: How to pair/multimap <int, pointer to a function>?
JohnW@Wessex, your suggestion is basically the same as std::function except more home-grown.
Quote:
What I would like to do is to build a multimap at run time. In the beginning the program reads in a file telling it which integer points to which member function. One integer may point to one or more member functions. A multimap is built according to the file content. After that the program receives integer input and calls the corresponding member function(s) in the multimap. (I haven't got to this part - not sure if I am on the right track yet.)
The key question you have not addressed is----call the member function of which object?
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
Lindley
JohnW@Wessex, your suggestion is basically the same as std::function except more home-grown.
Ah, interesting.
I've not had the opportunity to use a compiler that supports std::function yet. :(
Re: How to pair/multimap <int, pointer to a function>?
Think of it as a generic function object. You can assign any functor or function pointer to it, so long as it matches the arguments and return type specified in the template. In C++03, many STL functions support arbitrary functors/function pointers, but they do it by making the type a template argument. That works fine for "one call" usage, but when you want to store these things in a container for later, it is insufficient. std::function fills that gap.
std::bind is a generalization of std::bind1st and std::mem_fun, etc in C++03. It can bind any number of arguments to any number of function or functor parameters, including binding the "this" to a member method, and return an appropriate functor. (In practice, some implementations of std::bind still have limits on the number of bindings. Variadic templates should eliminate this limitation when they are better supported.)
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
acppdummy
What I would like to do is to build a multimap at run time. In the beginning the program reads in a file telling it which integer points to which member function. One integer may point to one or more member functions.
OK. Given this, do you know the syntax to call a non-static member function using a pointer? It is far different than making "normal" non-static member function calls via pointer, which is the point Lindley made.
You need an object in the call syntax. Without it, your design needs to be redone.
Regards,
Paul McKenzie
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
Lindley
It can bind [...] including binding the "this" to a member method, and return an appropriate functor
note that an std::function plus a lambda capture is better suited for this purpose, being the former required to store the 'this' pointer internally in the function object instead of invoking the heap; AFAIK, this guarantee doesn't hold for std::bind.
Re: How to pair/multimap <int, pointer to a function>?
Some implementations of lambdas (VS10, I think) doesn't handle the capture of "this" properly just yet. You can get around it by assigning this to a local pointer before the lambda.
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
Lindley
...
The key question you have not addressed is----call the member function of which object?
Sorry. I was thinking something like this:
Code:
myclass mc;
mc.readfileandmakemultimap();
// get integer input and call corresponding mc.fun1() mc.fun2() etc.
// not sure how to do it though
Quote:
Originally Posted by
Paul McKenzie
OK. Given this, do you know the syntax to call a non-static member function using a pointer? It is far different than making "normal" non-static member function calls via pointer, which is the point Lindley made.
I don't know. Any suggestions? Thanks!
Quote:
You need an object in the call syntax. Without it, your design needs to be redone.
I won't mind redoing if I know how to. Any suggestion on how exactly to redo it is welcome. Thanks!
Re: How to pair/multimap <int, pointer to a function>?
Quote:
Originally Posted by
acppdummy
I don't know.
Then that's a problem.
Code:
class MyObject
{
public:
int SomeFunc(int);
};
typedef int (MyObject::*fn)(int);
int main()
{
fn MyFnPtr = &MyObject::SomeFunc;
MyObject object; // create an instance of MyObject
(object.*MyFnPtr)(10);
}
Look at the line in red. You see that the object instance must be part of the syntax to call a non-static member function. If you were thinking it would look like your 'C' function call syntax, you were wrong.
Code:
typedef int (*fn)(int);
int SomeFunc(int);
int main()
{
fn MyFnPtr = &SomeFunc;
(*fn)(10); // C-style function
}
Note the vast difference.
So where is "object" in your multimap design going to come from?
Regards,
Paul McKenzie