Boost.Any得到原始类型

时间:2012-02-02 00:15:13

标签: c++ boost types

我需要将any变量转换为原始类型。 我需要这样做:

int i = 10;
any a(i);
int& i2 = any_cast<int &>(a);

但我希望类型存储在any变量中。我写这个:

int i = 10;
any a(i);
a::type_value& i2 = any_cast<a::type_value &>(a); // there is no actually type_value

我该怎么办?或者如何从any变量中提取原始类型? Boost.variant也很方便。

如果我不能这样做,那么我还有另一个问题,C ++技术和库可以存储什么,并通过函数获取类型来解决这个问题?

2 个答案:

答案 0 :(得分:16)

C ++是一种静态类型语言。 boost::any的类型是运行时值;任何特定的any都可以有任何类型。这有点重要。

没有any::type_value,因为那必须是编译时值。 any是一个运行时构造。

考虑一下:

void TakeAnAny(boost::any a)
{
  a::type_value& i2 = any_cast<a::type_value &>(a);
}

any::type_value是什么类型的?使用虚拟任何类型调用TakeAnAny是合法的。 any::type_value可以减少的单一编译时类型没有。因此,编译器无法确定类型。由于C ++是静态类型的,所以你已经被软管了。

任何一个的最终目的是类型擦除。我有一些价值。我想把它传递给其他一些功能。此过程将通过几个不同的通信层。但我不一定希望所有这些不同的层确切地知道我正在使用的是什么类型。我只需要自己和我想要的目的地来了解类型。所以你坚持使用any并且你很好。其他人只看到any,你们两个都知道它的内容。

此过程仅起作用,因为源和目标都知道值的实际类型。如果您不知道类型,则不应使用anyany的目的是没有函数,并将其转换为一堆可能的类型(这就是boost::variant的用途)。目的是从函数的签名中删除类型。

这允许通用消息和信号之类的东西。您在系统中注册了一些事件处理程序。您触发一个以any为参数的事件。触发事件的人知道“MouseClick”事件总是以vec2为参数。因此,每个“MouseClick”处理程序都将其转换为vec2。 “KeyPress”事件可能会传递int32_t。所以那些处理程序将它转换为该类型。等等。每个人都知道它实际需要什么类型。

过去常常使用void*。问题在于您有所有权问题(any是值,而void*是指针)。此外,void*是如此类型删除,以至于无法检查您的演员表是否正确。 any实际上只是一种类型和价值安全的void*;它会阻止您转换为错误的类型。

你真的不想any。您的用例似乎也不需要variant。您似乎想要的是模板。这是一种不同的东西,它可以让你做你真正想要的东西:拥有一个可以使用任何特定类型的功能,同时仍然能够确切知道该类型是什么。

当然,模板有其自身的局限性。

答案 1 :(得分:1)

您可以使用std::type_infostd::function<void(boost::any const&)>对象的地图来处理您想要处理的类型:您可以使用{{1}在地图中找到该条目并调用相应的函数,该函数将知道如何处理参数。