C ++相当于C#4.0的“动态”关键字?

时间:2010-11-12 02:52:32

标签: c++ dynamic c++11 dynamic-typing

在C#4.0中,您可以使用“dynamic”关键字作为占位符,直到运行时才知道该类型。在某些极端情况下,这是非常有用的行为。是否可以在C ++中模拟这样的事情,可能使用C ++ 0x功能或RTTI?

6 个答案:

答案 0 :(得分:4)

不是真的。您可以获得的最接近的是void *,但在使用它之前,您仍需要将其强制转换为适当的类型。

<强>更新

  

尝试构建一个基本上编译为C ++的鸭式DSL。

你可以通过至少两种方式解决这个问题:

基于联盟的变体

struct MyType {
  enum { NUMBER, STRING /* etc */ } type;
  union {
    double number;
    string str;
  };
};

多态类层次

class MyType {
public:
  /* define pure virtual operations common to all types */
};

class MyNumber : public MyType {
private:
  double number;
public:
  /* implement operations for this type */
};

答案 1 :(得分:4)

C#的dynamic功能高度依赖于.NET的内置反射功能。由于标准C ++几乎不提供反射支持,因此无法获得类似的行为。 RTTI将允许您安全地向下转换指针,但这几乎就是它。你仍然可以枚举字段和方法并动态调用它们。

答案 2 :(得分:2)

正如其他人已经说的那样,在一般情况下这是不可能的,但我认为如果不这样做会有所帮助。

问题有两个层次,句法层面和语义层面。

在句法层面,您有以下代码:

dynamic d = /* something */;
d.Foo(bar); // Foo is unknown at compile time

在.NET中dynamic是一个编译器功能,它所做的不是生成函数调用而是创建一个包含函数名称的调用站点和参数类型(用于重载)。这意味着如果您想支持动态,则拥有来修改编译器。确实,模板元编程允许做类似的事情,但TMP本质上是在编译时完成的,因此不能完成支持运行时调用的工作。

如果你不是关于语法的肛门,那么你可以支持这样的事情:

dynamic d = /* something */;
d.invoke("Foo", bar);

在语义层面 正如@Trillian(酷用户名BTW)所说,动态依赖于反射,这不是严格正确的,你可以指定dynamic is implemented如何,而CLR类型的默认值是反射,所以绑定的类型到dynamic变量必须支持某种运行时检查(例如COM的IDispatch)。对于C ++中的一般情况,情况并非如此,但如果您只能将支持范围缩小到支持(已知)类型检查的类型,则可以在C ++中实现dynamic(如上所述,没有语法)。 / p>

答案 3 :(得分:0)

这是不可能的。需要在编译时知道对象大小,因此堆栈指针可以移动适当的字节数。如果您没有声明类型,那么编译器将不知道大小。 C#通过创建所有对象指针来解决这个问题。

答案 4 :(得分:0)

example on github提供了一种可能的实现方式,具体取决于您的功能复杂程度。

template <typename X, typename Y>
auto add(X x, Y y) -> decltype(x + y) {
  return x + y;
}
add(1, 2); // == 3
add(1, 2.0); // == 3.0
add(1.5, 1.5); // == 3.0

答案 5 :(得分:-1)

我想不出一个可能的代码路径,其中值的类型实际上一直未知,直到运行时。即使您将两个模块链接在一起(动态地,在运行时),两者都已经编译,并且它们可以返回的类型也完全确定,并且实际上编码为库公开的符号的错位名称。

但是,在实际编译代码之前,您可以推迟对类型的了解。在C ++ 0x中,有auto关键字,它从用于初始化变量的表达式提供类型推断,在当前的C ++中,您可以使用模板,如下所示:

template<typename T>
T square(const T& someArg){
   return T*T;
}

编辑:根据您对问题的评论,您可能没有类型未知的情况。更有可能的是,该类型仅限于少数(预定义)类型中的一种。为此,您可以使用union类型,最好使用boost::variant