我希望这个标题能够真正描述我想要问的内容......
我写了一段代码,用gcc编译并按照我的意图工作。但是,它不会使用llvm进行编译,并且在使用icc编译时代码执行方式不同! 以下是问题的一个示例:
#include <iostream>
using std::cout; using std::endl;
class A {
public:
virtual void foo() { cout << "A::foo()" << endl; }
};
class B : public A {
public:
typedef A base;
virtual void foo() { cout << "B::foo()" << endl; }
};
int main() {
typedef B base;
base* bp = new B();
bp->base::foo();
}
gcc输出:A :: foo()
icc输出:B :: foo()
有人可以解释标准对此案例的评价吗?
答案 0 :(得分:7)
来自C ++ 11,§3.4.5/ 4:
如果类成员访问中的id-expression是。的限定id 形成class-name-or-namespace-name::...class-name-or-namespace-name 跟着。或 - &gt;操作员是第一次在班上查找的 使用对象表达式和名称(如果找到)。否则就是 在整个postfix-expression的上下文中查找。
我认为它不会更清楚。这会找到B::base
,因此输出
应该是A::foo()
。
答案 1 :(得分:6)
我认为标准的这一部分是相关的:
在这种情况下,3.4.3.1班级成员[class.qual]
1)如果qualified-id的nested-name-specifier指定了一个类,则在 在类的范围内查找嵌套的namespecifier(10.2), 除下列案例外。名称应代表一个或 该类或其中一个基类的更多成员(第10条)。 [注意:可以在任何时候使用qualified-id引用类成员 指出其潜在范围(3.3.7)。 -end note]例外 上面的名称查找规则如下:
- 析构函数名称是 按3.4.3的规定抬头;
- a的转换类型ID 转换函数id以与a相同的方式查找 类成员访问中的conversion-type-id(见3.4.5);
- 名字 在上下文中查找模板ID的模板参数 其中发生整个后缀表达式。
- 查找名称 在using-declaration(7.3.3)中指定也可以找到class或 隐藏在同一范围内的枚举名称(3.3.10)。
base::
似乎在提名&#34;一个类,所以查找是在类的范围内完成的。我不知道任何异常情况如何适用,因此它是类的范围,因此base
等同于A
。
(5.1.1-8表示在这种情况下它是一个合格的id并且3.4.3.1适用)