0

次のコードがあるとします。

namespace x{
    class X{
        virtual void x(){}
    }
}

namespace y{
    class Y : public x::X{
         void x(){}
    }
}

int main(){
    x::X* a = new y::Y();
    a->x::X::x(); //Tries to access x::X::x non-virtually. 
                  //Fails, since it treats the first x as the 
                  //function name instead of the namespace
}

ご覧のとおり、mainメソッドの最後の行は、クラスx :: Xのxメソッドを静的に(つまり非仮想的に)呼び出そうとします。ただし、名前空間はメソッドと同じ名前(両方ともxという名前)であるため、これは失敗します。したがって、コンパイラは最初のxをメソッド名として扱い、x::Xが意味をなさないと文句を言います。

この問題は一見仮想的に見えるかもしれませんが、実際にはコードに現れます。名前空間は大きなプロジェクトの名前空間であるため、簡単に名前を変更することはできません。メソッド名は、スコープ外の他のスーパークラス(ライブラリクラス)に準拠している必要があるため、変更できません。

それで、この構文をなんらかの方法で明確にして、メソッドx :: X :: xを非仮想的に呼び出すことができるようにする機会はありますか?

今のところ、私が見ている唯一の解決策は、x :: Xをtypdefしてから、typedefを使用することです。typedefなしの解決策はありますか?

4

2 に答える 2

5
a->x::X::x(); //Tries to access x::X::x non-virtually. 
              //Fails, since it treats the first x as the 
              //function name instead of the namespace

それは実際には問題の非常に明確な説明です。x::解決策は、資格の一部を削除することです。ルックアップが開始され、そのコンテキストでのY検索に失敗するとX、階層を上に移動して、クラスX内に挿入された名前として検索されます。X

于 2012-08-20T12:15:29.340 に答える
0

typedefとあまり変わらないと思いますが、それでも...

using namespace xAlias = x;
于 2012-08-20T12:26:39.140 に答える