-1

このようなコードをMSVS6からVS2010に移行しています。

class A
{
protected:
    typedef void (A::*X_t)(int x);
    virtual void CallX(X_t x) {}
    virtual void X() {}
    virtual void X(int x) {}
};

class B: public A
{
protected:
    virtual void X()
    {
        this->CallX(&A::X);
    }    
};

これはMSVS6でコンパイルされますが、VS2010では失敗します

error C2248: 'A::X' : cannot access protected member declared in class 'A'

このエラーから抜け出す方法はありますか?

4

1 に答える 1

2

標準の11.4/1を見ると、正直なところ、この言語は私を混乱させます。しかし、例はかなり明確です。

class B {
protected:
    int i;
    static int j;
};

class D1 : public B {
};

class D2 : public B {
    friend void fr(B*,D1*,D2*);
    void mem(B*,D1*);
};

... irrelevant stuff snipped

void D2::mem(B* pb, D1* p1) {
    ...
    int B::* pmi_B = &B::i; // ill-formed  *****this*****
    int B::* pmi_B2 = &D2::i; // OK
    ...
}

ここでのテキストは、標準から直接ではありませんが、より明確です。

フレンドの基本クラスAの保護された非静的メンバーxまたは派生クラスBのメンバー関数を参照する場合は、Aから派生したクラスへのポインター、参照、またはオブジェクトを介してxにアクセスする必要があります。 xにアクセスしてメンバーへのポインターを作成する場合は、派生クラスBに名前を付けるネストされた名前指定子でxを修飾する必要があります。

したがって、ここでの私の理解が正しければ、VisualStudioはこれを拒否する権利があります。

これを修正するために、これが正しいかどうかはわかりませんが、VS2012で問題が修正されたようです。

 this->CallX(&B::A::X);

ただし、同じことがclangでは機能しないようです。

于 2013-02-15T10:04:23.830 に答える