C++ method call and type scope resolution ambiguity

余生长醉 提交于 2019-12-20 18:16:44

问题


I hope the title actually describes what I wanted to ask...

I wrote a piece of code that compiles with gcc and works as I intended. However, it does not compile with llvm and the code executes differently when compiled with icc!
Here is an example of the problem:

#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 output: A::foo()
icc output: B::foo()

Could somebody explain what does the standard say about this case?


回答1:


From C++11, §3.4.5/4:

If the id-expression in a class member access is a qualified-id of the form
    class-name-or-namespace-name::...
the class-name-or-namespace-name following the . or -> operator is first looked up in the class of the object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression.

I don't think it can be clearer. This finds B::base, so the output should be A::foo().




回答2:


I think this part of the standard is relevant:

3.4.3.1 Class members [class.qual]

1) If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-namespecifier is looked up in the scope of the class (10.2), except for the cases listed below. The name shall represent one or more members of that class or of one of its base classes (Clause 10). [ Note: A class member can be referred to using a qualified-id at any point in its potential scope (3.3.7). —end note ] The exceptions to the name lookup rule above are the following:

— a destructor name is looked up as specified in 3.4.3;

— a conversion-type-id of a conversion-function-id is looked up in the same manner as a conversion-type-id in a class member access (see 3.4.5);

— the names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression occurs.

— the lookup for a name specified in a using-declaration (7.3.3) also finds class or enumeration names hidden within the same scope (3.3.10).

base:: in this case seems to "nominate" a class, so the look up is done in scope of the class. I don't see how any of the exception cases could apply, so it is the scope of the class, as such base is equivalent to A.

(5.1.1-8 indicates that it is a qualified-id in that case and that 3.4.3.1 applies)



来源:https://stackoverflow.com/questions/11115484/c-method-call-and-type-scope-resolution-ambiguity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!