我正在将这样的代码从MS VS6迁移到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);
}
};
这是在MS VS6中编译的,但在VS2010中它在
上失败error C2248: 'A::X' : cannot access protected member declared in class 'A'
有没有办法摆脱这个错误?
答案 0 :(得分: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
...
}
文本here虽然不直接来自标准,但更为明确。
如果引用a中基类A的受保护非静态成员x 朋友或派生类B的成员函数,您必须访问x 通过指向,引用或从中派生的类的对象 答:但是,如果您正在访问x以创建指向成员的指针,那么 必须使用命名派生的嵌套名称说明符限定x B级。
所以,如果我的理解在这里是正确的,那么Visual Studio拒绝这一点是正确的。
要修复它,我不确定这是否正确,但它似乎在VS2012中解决了我的问题:
this->CallX(&B::A::X);
然而,同样的事情似乎不适用于clang。