访问私有嵌套类定义的行为不一致

3

我有一段代码,声明了一个子类模板为私有的,然后声明了一个成员为受保护的:

class X {
private:
    template <class T>
    class Y {
    public:
        void somethingToDo();
        // definition
    };
protected:
    Y<SomeType> _protectedMember;
    // More definition
};

class Z : public virtual X{
public:
    void f();
}
void Z::f() {
    ...
    _protectedMember.somethingToDo();
}

最初我使用gcc 4.3.4编译这个程序,它成功了。然后我尝试在各种平台上使用GCC、IBM和Microsoft编译器构建,非GCC编译器都拒绝了它。现在看起来好像是(这个版本的)gcc不符合标准。但在得出任何结论之前,我想验证一下什么是技术上正确的。

谢谢。


假设您希望 Z::fpublic最新的GCC正确地拒绝了该代码 - Xeo
我本意是让Z::f成为公共的。我会修正这个问题。 - shroudednight
Y<T>::somethingToDo 真的意味着是私有的吗? - usta
1
就目前而言,这个程序可以使用 g++4.7 和 g++-4.5编译成功。 - Robᵩ
如所请求:http://ideone.com/xyDoT。诚然,我在原问题中并没有很好地描述实际情况。但是,我可以确认链接的代码在GCC中可以编译而在其他程序中无法编译。目前,我对原问题该怎么处理还不确定,因为我实际上也不理解之前链接的程序(其准确反映了问题)为什么能编译。 - shroudednight
显示剩余5条评论
3个回答

1

我相信我以前见过这个。当时这是GCC中的已知错误,现在已经修复了。


听起来很相似,但我不确定这是否与此案例中对受保护成员的访问有关。在这种情况下,应该或不应该允许访问类型定义。 - shroudednight

1

你的程序在我看来是有效的(除了Y::somethingToDo是毫无意义的私有)。Z::f()没有请求访问任何private名称,只有protected的。

如果Z::f()试图引用Y<T>,那么编译器应该会出错。但是Z::f()只访问了_protectedMember,这肯定是允许的。


0

你的 Y 模板是私有的,不能在非私有的代码中使用,比如 _protectedMember,它旨在从派生类中访问,你应该将其声明为受保护的,这样它的成员才能被派生类看到。

一般规则是,如果你想让你的变量在某个范围内完全可访问,那么它的类型必须在该范围内完全可访问。当然,在当前设计下,你的代码可以在以下情况下很有用:

class Base {
    class PrivateClass {};
protected:
    PrivateClass _val;
    void doSomething( PrivateClass& v );
}

现在派生类可以使用_val来调用doSomething,但是它们不能调用其方法或使用其属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接