I want to use boost::any to store heterogeneous function pointers. I get an exception when I try to use boost::any_cast to recast to the function pointer.
Is what I want to do even allowed?
.h:
typedef void(*voidFunction)(void);
struct functionInfo{
CString functionName;
boost::any functionPointer;
};
void foo();
int foo2(int a);
.cpp
void foo()
{
;//do something
}
int foo2(int a)
{
;//do something
}
void main()
{
vector<functionInfo> functionList;
functionInfo myInfo;
myInfo.functionName = _T("foo");
myInfo.functionPointer = &foo;
functionList.push_back(myInfo);
myInfo.functionName = _T("foo2");
myInfo.functionPointer = &foo2;
functionList.push_back(myInfo);
voidFunction myVoidFunction = boost::any_cast<voidFunction>(functionList[0].functionPointer);
}
----EDIT----
Ok, you are right, the reason why it acted like this is because foo is a class member function.
Meaning:
void MyClass::foo();
myInfo.functionPointer = &MyClass::foo;
so I needed to typedef:
typedef void(MyClass::*voidClassFunction)(void);
voidClassFunction myVoidFunction = boost::any_cast<voidClassFunction>(functionList[0].functionPointer);
Absolutely. As long as you cast it back to exactly the type you gave it.
And that's your problem. You don't.
foo2is not avoidFunction. Therefore, you cannot cast it to one.The purpose of
boost::anyis to have avoid*that is guaranteed to either work correctly according to the C++ standard or throw an exception. The C++ standard allows the conversion of any (non-member) pointer type to avoid*. It also allows conversion of avoid*back to a type, provided that the type being provided is exactly the same type as the original. If it's not, welcome to undefined behavior.boost::anyexist to prevent undefined behavior by storing type information with thevoid*. It will rightly throw an exception when you attempt to cast something to the wrong type. As you do here.boost::anyis not a way to pretend that types don't exist and to pretend that you can turn anything into something else. It's just a type-safe typeless container. You still need to know what you actually put there.There is no way to store a list of functions with arbitrary argument lists and call them with the same argument list. The user must provide a function or functor with the right argument list that you expect.
boost::bindis a way to adapt a function/functor for a particular argument list, but the user must explicitly use it.The best you can do is have a list of specific function parameter sets that you accept, stored in a
boost::variantobject. You can use a visitor to figure out which particular function to call.