简体   繁体   English

Boost.Any得到原始类型

[英]Boost.Any get original type

I need to cast an any variable to an original type. 我需要将any变量转换为原始类型。 I need to do this: 我需要这样做:

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

But I want that the type stores in any variable. 但我希望类型存储在any变量中。 And I write this: 我写这个:

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

How can I do something like that? 我怎么能这样做? Or how can I extract the original type from the any variable? 或者我如何从any变量中提取原始类型? Boost.variant is convenient either. Boost.variant也很方便。

If I cannot do that, then I have another question what C++ techniques and libraries can store and get the type through a function to solve this issue? 如果我不能这样做,那么我还有另一个问题,C ++技术和库可以存储什么,并通过函数获取类型来解决这个问题?

C++ is a statically typed language. C ++是一种静态类型语言。 The type of a boost::any is a runtime value; boost::any的类型是运行时值; any particular any could have any type. 任何特定any可以有任何类型。 That's kinda the point. 这有点重要。

There is no any::type_value , because that would have to be a compile time value. 没有any::type_value ,因为那必须是编译时的值。 And any is a runtime construct. any都是运行时构造。

Consider this: 考虑一下:

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

What type is any::type_value ? 什么类型是any::type_value It is legal to call TakeAnAny with virtually any type. 几乎任何类型的呼叫TakeAnAny是合法的。 There is no single compile-time type that any::type_value could reduce to. 没有any::type_value可以减少的单一编译时类型。 And therefore, there is no way for the compiler to determine a type. 因此,编译器无法确定类型。 Since C++ is statically typed, you're hosed. 由于C ++是静态类型的,所以你就被软管了。

The ultimate purpose of any is type-erasure. 任何一个的最终目的是类型擦除。 I have some value. 我有一些价值。 And I want to pass that to some other function. 我想把它传递给其他一些功能。 This process will go through several different communication layers. 此过程将通过几个不同的通信层。 But I don't necessarily want all of those different layers to know exactly what type I'm using. 但我不一定希望所有这些不同的层确切地知道我正在使用的是什么类型。 I only need myself and my intended destination to know the type. 我只需要自己和我想要的目的地来了解类型。 So you stick it in an any and you're fine. 所以你把它粘在any一个你很好。 Everyone else just sees the any , and both of you know what it wraps. 其他人只看到any ,你们两个都知道它包装的内容。

This process only works because both the source and the destination know the real type of the value. 此过程仅起作用,因为源和目标都知道值的实际类型。 If you don't know the type, then you shouldn't be using any . 如果您不知道类型,那么您不应该使用any The purpose of any is not have a function sit there and cast it to a bunch of possible types (that's what boost::variant is for). any的目的是没有函数坐在那里并将其转换为一堆可能的类型(这就是boost::variant的用途)。 The purpose is to erase the type from a function's signature. 目的是从函数的签名中删除类型。

This allows for things like generic messages and signals. 这允许通用消息和信号之类的东西。 You register some event handler with a system. 您在系统中注册了一些事件处理程序。 You fire an event that takes an any as a parameter. 您触发一个以any作为参数的事件。 The person firing the event knows that the "MouseClick" event always takes a vec2 as its parameter. 触发事件的人知道“ vec2 ”事件总是以vec2为参数。 So every "MouseClick" handler casts it to a vec2 . 所以每个“ vec2 ”处理程序都将它转换为vec2 The "KeyPress" event would maybe pass a int32_t . “KeyPress”事件可能会传递一个int32_t So those handlers cast it to that type. 所以那些处理程序将它转换为该类型。 And so forth. 等等。 Everyone knows what type it actually takes. 每个人都知道它实际需要什么类型。

This used to be done with void* . 过去常常用void*来完成。 The problem there is that you have ownership issues ( any is a value, while void* is a pointer). 问题是你有所有权问题( any是一个值,而void*是一个指针)。 Also, a void* is so type-erased that there's no way to check to see if your cast is correct. 此外, void*是如此类型擦除,因此无法检查您的演员是否正确。 any is really just a type&value-safe void* ; any只是一种类型和价值安全的void* ; it prevents you from casting to the wrong type. 它可以防止你输入错误的类型。

You don't really want any . 你真的不想要any Your use case doesn't seem to want variant either. 您的用例似乎也不需要variant What you seem to want is a template . 你似乎想要的是一个模板 That's a different kind of thing, and it would let you do what you really want: have a function that can use any particular type, while still being able to know exactly what that type is. 这是一种不同的东西,它可以让你做你真正想要的东西:拥有一个可以使用任何特定类型的功能,同时仍然能够确切知道该类型是什么。

Of course, templates have their own limitations. 当然,模板有其自身的局限性。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM