17

タイトルが私が聞きたかったことを実際に表していることを願っています...

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()

誰かがこのケースについて標準が何を言っているのか説明できますか?

4

2 に答える 2

7

C++11 から、§3.4.5/4:

クラス メンバー アクセスの id-expression がフォームの修飾 ID である場合
    クラス名または名前空間名::...
に続くクラス名または名前空間名。or -> 演算子は最初にオブジェクト式のクラスで検索され、見つかった場合はその名前が使用されます。それ以外の場合は、postfix-expression 全体のコンテキストで検索されます。

私はそれがより明確になるとは思わない。これは を見つけるB::baseので、出力は になるはずですA::foo()

于 2012-06-20T09:04:34.853 に答える
6

私は、標準のこの部分が関連していると思います:

3.4.3.1 クラスメンバー [class.qual]

1) 修飾 ID のネストされた名前指定子がクラスを指名する場合、ネストされた名前指定子の後に指定された名前は、以下にリストされている場合を除いて、クラス (10.2) のスコープで検索されます。名前は、そのクラスまたはその基本クラスの 1 つの 1 つまたは複数のメンバーを表すものとします (条項 10)。[ 注: クラス メンバーは、潜在的なスコープ (3.3.7) 内の任意のポイントで修飾 ID を使用して参照できます。—終わりの注] 上記の名前検索ルールの例外は次のとおりです。

— デストラクタ名は、3.4.3 で指定されているように検索されます。

— conversion-function-id の conversion-type-id は、クラス メンバ アクセスの conversion-type-id と同じ方法で検索されます (3.4.5 を参照)。

— template-id の template-argument 内の名前は、postfix-expression 全体が発生するコンテキストで検索されます。

— using-declaration (7.3.3) で指定された名前の検索では、同じスコープ (3.3.10) 内に隠されているクラスまたは列挙名も検出されます。

base::この場合、クラスを「指名」しているように見えるため、ルックアップはクラスのスコープで行われます。例外ケースがどのように適用されるかはわかりません。したがって、それはクラスのスコープでありbaseA.

(5.1.1-8 は、その場合は修飾 ID であり、3.4.3.1 が適用されることを示します)

于 2012-06-20T08:50:18.643 に答える