C ++方法调用和类型范围解析模糊

时间:2012-06-20 08:21:03

标签: 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(); 
}

gcc输出:A :: foo()
icc输出:B :: foo()

有人可以解释标准对此案例的评价吗?

2 个答案:

答案 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适用)