繁体   English   中英

dynamic_cast混乱

[英]dynamic_cast confusion

我放弃了......

$ 5.2.7 / 2-“如果T是指针类型,则v应该是指向完成类类型的指针的右值,结果是类型为T的rvalue。如果T是引用类型,则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应该是多态类型的指针或左值(10.3)。

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

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

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

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

为了像你的例子那样做一个向下转换 ,结构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下工作

“否则”在这种情况下意味着“除非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没有“否则”(除非它说“否则,符合标准的编译器必须发出诊断”,但这是隐含的)

暂无
暂无

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

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