Now*_*kus 18 c++ types scope ambiguity method-call
我希望这个标题能够真正描述我想要问的内容......
我编写了一段代码,用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();
}
Run Code Online (Sandbox Code Playgroud)
gcc输出:A :: foo()
icc输出:B :: foo()
有人可以解释标准对这个案子的看法吗?
从C++ 11,§3.4.5/ 4:
如果类成员访问中的id-expression是表单的qualified-id
class-name-or-namespace-name::...
下面的class-name-or-namespace-name.或 - >运算符首先在对象表达式的类中查找,如果找到,则使用名称.否则,它将在整个postfix-expression的上下文中查找.
我认为它不会更清楚.这找到了B::base,所以输出应该是A::foo().
我认为标准的这一部分是相关的:
3.4.3.1班级成员[class.qual]
1)如果qualified-id的nested-name-specifier指定了一个类,则在类(10.2)的范围内查找在嵌套的namespecifier之后指定的名称,但下面列出的情况除外.该名称应代表该类别或其基类之一的一个或多个成员(第10条).[注意:可以在潜在范围内的任何一点使用qualified-id引用类成员(3.3.7).-end note]以上名称查找规则的例外情况如下:
- 按3.4.3中的规定查找析构函数名称;
- 以与成员访问中的conversion-type-id相同的方式查找conversion-function-id的conversion-type-id(参见3.4.5);
- 在发生整个后缀表达式的上下文中查找template-id的template-argument中的名称.
- 查找using-declaration(7.3.3)中指定的名称还会查找隐藏在同一范围内的类或枚举名称(3.3.10).
base::在这种情况下似乎"提名"一个类,所以查找是在类的范围内完成的.我没有看到任何异常情况如何应用,因此它是类的范围,因此base等同于A.
(5.1.1-8表示在这种情况下它是一个合格的id并且3.4.3.1适用)