从 boost::any 恢复函数指针

发布于 2024-12-11 12:48:30 字数 1190 浏览 0 评论 0原文

我想使用 boost::any 来存储异构函数指针。当我尝试使用 boost::any_cast 重新转换为函数指针时出现异常。

我想做的事情是否被允许?

.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);

}

----编辑----

好的,你是对的,之所以这样,是因为 foo 是一个类成员函数。

意思是:

void MyClass::foo();

myInfo.functionPointer = &MyClass::foo;

所以我需要输入:

typedef void(MyClass::*voidClassFunction)(void);
voidClassFunction myVoidFunction = boost::any_cast<voidClassFunction>(functionList[0].functionPointer);

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不再见 2024-12-18 12:48:30

我想做的事情是否被允许?

绝对地。只要您将其精确地转换回您指定的类型即可。

这就是你的问题。你不知道。 foo2 不是 voidFunction。因此,您不能将其转换为一。

boost::any 的目的是保证 void* 要么根据 C++ 标准正确工作,要么抛出异常。 C++ 标准允许将任何(非成员)指针类型转换为 void*。它还允许将 void* 转换回类型,前提是提供的类型与原始类型完全相同。如果不是,欢迎使用未定义的行为。

boost::any 的存在是为了通过使用 void* 存储类型信息来防止未定义的行为。当您尝试将某些内容转换为错误的类型时,它会正确地抛出异常。正如你在这里所做的那样。 boost::any 并不是一种假装类型不存在以及假装可以将任何东西变成其他东西的方法。它只是一个类型安全的无类型容器。您仍然需要知道您实际放在那里的是什么。

无法存储具有任意参数列表的函数列表并使用相同的参数列表调用它们。用户必须提供具有您期望的正确参数列表的函数或函子。 boost::bind 是一种使函数/函子适应特定参数列表的方法,但用户必须显式使用它。

您能做的最好的事情就是拥有一个您接受的特定函数参数集的列表,并将其存储在 boost::variant 对象中。您可以使用访问者来确定要调用哪个特定函数。

Is what I want to do even allowed?

Absolutely. As long as you cast it back to exactly the type you gave it.

And that's your problem. You don't. foo2 is not a voidFunction. Therefore, you cannot cast it to one.

The purpose of boost::any is to have a void* 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 a void*. It also allows conversion of a void* 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::any exist to prevent undefined behavior by storing type information with the void*. It will rightly throw an exception when you attempt to cast something to the wrong type. As you do here. boost::any is 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::bind is 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::variant object. You can use a visitor to figure out which particular function to call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文