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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (20)

我写了一段代码,用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()

有人可以解释标准对这种情况的说法吗?

提问于
用户回答回答于

从C ++ 11,§3.4.5/ 4开始:

如果类成员访问中的id表达式是表单的限定标识 类名称或名称空间名称:: ... 后面的class-name-or-namespace-name。或 - >运算符首先在对象表达式的类中查找,并使用名称(如果找到)。否则,它将在整个后缀表达式的上下文中查找。

我不认为它可以更清楚。这发现B::base,所以输出应该是A::foo()

用户回答回答于

我认为这部分标准是相关的:

3.4.3.1班级成员[class.qual] 1)如果qualified-id的嵌套名称说明符指定了一个类,则除了下面列出的情况外,在类(10.2)的范围内查找nested-namespecifier后面指定的名称。该名称应代表该类别或其基类之一或多个成员(第10条款)。[注意:一个类成员可以在其潜在作用域(3.3.7)中的任何一点使用一个限定的id来引用。 - 注意]上面的名称查找规则的例外情况如下: - 按照3.4.3的规定查找析构函数名称; - 转换功能id的转换类型id在类成员访问中以与转换类型id相同的方式查找(见3.4.5); - 在整个postfix-expression发生的上下文中查找template-id的template-argument中的名称。 - 查找使用声明(7.3.3)中指定的名称时,也会查找隐藏在相同范围(3.3.10)内的类或枚举名称。

base::在这种情况下,似乎是“提名”一个班级,所以查询是在班级范围内完成的。我不明白任何例外情况如何适用,所以这是类的范围,因为这base相当于A

(5.1.1-8表示在这种情况下它是一个合格的身份证,并且适用3.4.3.1)

扫码关注云+社区