dynamic_cast混乱

时间:2010-11-17 10:30:57

标签: c++ dynamic-cast

我放弃了......

  

$ 5.2.7 / 2-“如果T是指针类型,v   应该是指针的右值   完整的类类型,结果是   类型为T的右值。如果T是a   参考类型,v应为左值   一个完整的类类型,和   结果是该类型的左值   由T提到。“

根据以上所述,以下代码应该是格式良好的。

struct A{};
struct B : A{};

int main(){
   B b;
   A a, &ar1 = b;

   B& rb1 = dynamic_cast<B&>(ar1);  // Does not $5.2.7/2 apply here?
   B& rb2 = dynamic_cast<B&>(a);    // and also here?
}

但事实并非如此。所有编译器都抱怨dynamic_cast的操作数不符合

的多态性
  

$ 5.2.7 / 6-否则,v应为a   指向或左值的   多态类型(10.3)。

所以我的问题是$ 5.2.7 / 2是什么意思?为什么$ 5.2.7 / 6会在这里开始?

3 个答案:

答案 0 :(得分:9)

嗯,5.2.7中的所有要求都应该一起观察。您不能在5.2.7 / 2之后停止并开始编写应该满足“高达5.2.7 / 2”的所有代码。整个5.2.7定义了dynamic_cast的规范。

多态性要求被挑选出来,因为它是条件。当您使用dynamic_cast进行上传时,多态要求不适用(事实上,dynamic_cast相当于上传中的static_cast。多态性要求仅适用于使用dynamic_cast进行向下转换或交叉广播时。

dynamic_cast的规范是按顺序组织的,这意味着它首先处理更简单的情况,然后进入更复杂的应用程序。您应该逐步阅读它,直到它涵盖您的具体情况。你沿着这条道路阅读的所有内容都会累积起来,“否则”意味着:“如果我们还没有覆盖你的案例,那么继续阅读”。

答案 1 :(得分:4)

为了像您的示例中那样执行向下转换,结构A需要是多态的,并且具有RTTI。这是一个有效的调整版本:

struct A{virtual void f(){}};
struct B : A{};

int main(){
   B b;
   A a, &ar1 = b;

   B& rb1 = dynamic_cast<B&>(ar1);  // Does not $5.2.7/2 apply here?
   //B& rb2 = dynamic_cast<B&>(a);    // and also here?
}

通过添加虚拟化使其具有多态性,为该类启用了RTTI,允许向下转换。

请注意,您的第二个示例无效 - 因为您正在将一个pod(a)转换为对pod的引用 - 这是不允许的。


更新

5.2.7.5不允许使用您的代码,5.2.7.6也不允许使用。我的调整使其在5.2.7.6下工作

答案 2 :(得分:3)

“否则”在这种情况下意味着“除非5.2.7 / 5中的条件适用”。

你可以说这是因为/ 2对程序提出了关于dynamic_cast的操作数的要求(注意“应该”的语言“v应该是左值”而不是“是”语言的“结果是左值”)。与标准中的其他位置一样,表达要求并不一定意味着它只是 要求。其他条款可以规定额外的要求。在这种情况下,/ 6表示额外的要求,仅在某些情况下适用,具体取决于T和静态类型v。

/ 3,/ 4,/ 5告诉你结果的,它们与/ 2中的要求完全一致。它们都不以“其他”开头。所以对我来说很明显,他们不会形成从/ 2开始的“else if”链。

某些括号或某些内容可能会使其更清晰(即/ 6中的“否则”适用于/ 5中的“if”,而不适用于/ 2,/ 3或/ 4中的“if”)。但这不是家庭风格。

除了其他任何东西之外,/ 5中的“否则”在逻辑上不能有意义地应用于/ 2中的条件。 / 1表示T必须是“指向或完全类类型的引用,或 cv void*”。 / 2包括两种情况 - 指针类型和引用类型。这就是一切。对于/ 2没有“否则”(除非它说“否则,符合标准的编译器必须发出诊断”,但这是隐含的)