C++相当于 C# 4.0 的“动态”关键词?
在 C# 4.0 中,您可以使用“dynamic”关键字作为直到运行时才知道的类型的占位符。在某些极端情况下,这是非常有用的行为。是否可以在 C++ 中模拟类似的内容,可能使用 C++0x 功能或 RTTI?
In C# 4.0, you can use the "dynamic" keyword as a placeholder for a type that is not known until runtime. There are certain corner cases where this is extremely useful behavior. Is it possible to emulate anything like this in C++, possibly using C++0x features or RTTI?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
并不真地。您可以获得的最接近的是
void *
,但您仍然需要将其转换为适当的类型,然后才能使用它。更新:
您至少可以通过两种方式来解决此问题:
基于联合的变体
多态类层次结构
Not really. The closest you can get is a
void *
, but you still need to cast it to an appropriate type before you can use it.Update:
You can go about this in at least two ways:
Union-based variant
Polymorphic class heirarchy
C# 的
动态
功能高度依赖于.NET 的内置反射功能。由于标准 C++ 几乎不提供反射支持,因此您无法获得类似的行为。 RTTI 将允许您安全地向下转换指针,但仅此而已。您距离枚举字段和方法并动态调用它们还有很长的路要走。C#'s
dynamic
feature is highly dependant on .NET's built-in reflection capabilities. As standard C++ offers next to no reflection support, there's no way you can get a similar behavior. RTTI will allow you to safely downcast pointers but that's pretty much it. You're still quite far to being able to enumerate fields and methods and invoke them dynamically.正如其他人已经说过的那样,这在一般情况下是不可能的,但我认为了解为什么不可以提供信息。
问题有两个层次,句法层次和语义层次。
在语法级别,您有以下代码:
在.NET中,
动态
是一个编译器功能,它的作用是代替生成函数调用它创建一个调用站点,其中包含函数名称和参数类型(用于重载)。这意味着如果您想支持动态,您必须修改编译器。确实,模板元编程允许执行类似的操作,但 TMP 本质上是在编译时完成的,因此无法胜任支持运行时调用的工作。如果您对语法不熟悉,那么您也许可以支持如下内容:
在语义级别
作为 @Trillian (顺便说一句,很酷的用户名)说,动态依赖于反射,这并不是严格正确的,您可以指定如何
实现了dynamic
,并且CLR类型的默认值是反射,因此绑定到dynamic
变量的类型必须支持某种运行时检查(例如COM的IDispatch
)。对于 C++ 中的一般情况并非如此,但如果您可以将支持范围缩小到仅支持(已知)类型检查的类型,则可以在 C++ 中实现dynamic
(没有上面提到的语法) )。As others already said this isn't possible in the general case but I think it would be informative to see why not.
There are two levels to the problem, the syntactic level and the semantic level.
On the syntactic level you have the following code:
In .NET
dynamic
is a compiler feature, what it does is instead of generating a function call it creates a call site which contains the function name and types of parameters (for overloading). This means that if you want to support dynamic you have to modify the compiler. It's true that template meta programming allows doing similar stuff but TMP is by its nature done at compile time and therefore won't be up to the job of supporting runtime invocation.If you're not anal about the syntax then you may be able to support something like this:
On the semantic level
As @Trillian (cool user name BTW) said, dynamic relies on reflection, this isn't strictly true, you can specify how
dynamic
is implemented, and the default for CLR types is reflection, so the type that bound to adynamic
variable must support some sort of runtime inspection (e.g. COM'sIDispatch
). This isn't true for the general case in C++ but if you can narrow your support only to types that support (a known) type of inspection you can implementdynamic
in C++ (sans the syntax as mentioned above).这是不可能的。需要在编译时知道对象大小,以便堆栈指针可以移动适当的字节数。如果您不声明类型,那么编译器将不知道大小。 C# 通过创建所有对象指针来解决这个问题。
It's not possible. Object sizes need to be known at compile-time, so the stack pointer can move by the appropriate number of bytes. If you don't declare the type, then the compiler won't know the size. C# gets around this problem by making all objects pointers.
这个 github 上的示例提供了一种可能的实现,具体取决于您的函数复杂性。
This example on github provides one possible implementation, depending on your function complexity.
我想不出一个可能的代码路径,其中值的类型在运行时之前实际上一直是未知的。即使您将两个模块链接在一起(在运行时动态地),两个模块都已编译,并且它们可以返回的类型也已完全确定,并且实际上被编码到库公开的符号的损坏名称中。
但是,您可以推迟了解类型,直到必须实际编译代码为止。在 C++0x 中,有
auto
关键字,它从用于初始化变量的表达式提供类型推断,在当前的 C++ 中,您可以使用模板,如下所示:编辑:基于您的注释关于你的问题,你可能没有遇到类型未知的情况。更有可能的是,该类型仅限于几种(预定义的)类型之一。为此,您可以使用
union
类型,最好使用boost::variant
I can't think of a possible code path where the type of a value is actually unknown all the way until run-time. Even if you are linking two modules together (dynamically, at run time), both are already compiled, and the types that they can return are also fully determined, and in fact encoded into the mangled names of the symbols the library exposes.
You can, however, defer knowledge of types until the code must actually be compiled. In C++0x, there's the
auto
keyword, which provides type inference from the expression used to initialize the variable, and in current C++, you can use templates, like so:Edit: based on your comment on your question, You probably don't have a situation where the type is unknown. What's more likely is that the type is limited to one of a few (predefined) types. for that, you can use a
union
type, preferably usingboost::variant