我放弃了......
$ 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?
}
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.所有编译器都抱怨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_castupcast时,多态要求不适用(事实上,dynamic_cast相当于static_castupcast).多态要求仅适用于dynamic_cast用于向下转换或交叉广播的情况.
规范dynamic_cast是按顺序组织的,这意味着它首先处理更简单的情况,然后进入更复杂的应用程序.您应该逐步阅读它,直到它涵盖您的具体情况.你沿着那条道路阅读的所有东西都是累积的,而"否则"意味着:"如果我们还没有覆盖你的情况,那就继续阅读".
在这种情况下,“否则”是指“除非 5.2.7/5 中的条件适用”。
您可以这么说,因为 /2 对程序提出了有关 the 操作数的要求dynamic_cast(请注意“v 应是左值”的“应”语言与“结果是左值”的“is”语言) 。与标准中的其他地方一样,表达要求并不一定意味着它是唯一的要求。其他条款可以规定额外的要求。在这种情况下,/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 没有“否则”(除非它说“否则,符合标准的编译器必须发出诊断”,但这是隐含的)