3

I have code that declares a subclass template as private and then a member as protected:

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

Originally I compiled this with gcc 4.3.4 and it accepted it. I then sent it off to try and build against GCC, IBM and Microsoft compilers on various platforms and the non-gcc compilers rejected it. Now that seems to be an indictment of (this version of) gcc's standards compliance. But before I come to any conclusions, I'd like to verify what is technically correct.

Thanks.

shroudednight
  • 605
  • 4
  • 16
  • Assuming you meant `Z::f` to be `public`, [the newest GCC correctly rejects the code](http://liveworkspace.org/code/b4befec799ca3cf26f48218356809edd). – Xeo Oct 02 '12 at 19:39
  • I did mean for Z::f to be public. I'll fix the question. – shroudednight Oct 02 '12 at 19:39
  • Is `Y::somethingToDo` really meant to be private? – usta Oct 02 '12 at 19:40
  • `SomeType` appears to be undefined. Can you post an complete, minimal, **actual** program that demonstrates the problem? See http://SSCCE.ORG/. – Robᵩ Oct 02 '12 at 19:46
  • @Robᵩ I'll try to create a live example. – shroudednight Oct 02 '12 at 19:49
  • 1
    FWIW, [this program](http://ideone.com/nNL4C) compiles with g++4.7 and g++-4.5. – Robᵩ Oct 02 '12 at 19:50
  • @Robᵩ: Except that `Y::f` was decidedly *private* in the question. – Xeo Oct 02 '12 at 19:59
  • @Xeo - you are right. I assume that was a typo on OP's part. – Robᵩ Oct 02 '12 at 20:02
  • As requested: http://ideone.com/xyDoT. Admittedly, I didn't do a good job at describing what was actually happening in the original question. However, I can confirm that the linked code compiles in GCC and doesn't compile for others. As it is, I'm not sure what to do with regards to the original question, as I don't really understand why the previously linked program (which accurately reflects the question) compiles either. – shroudednight Oct 02 '12 at 20:39
  • Re: Y::somethingToDo being private, I can confirm it was a typo. – shroudednight Oct 02 '12 at 20:50

3 Answers3

1

I'm pretty sure I've seen this before. It was a known bug in GCC at the time and has since been fixed.

Michael Kristofik
  • 34,290
  • 15
  • 75
  • 125
  • That sounds similar, I'm not sure it's the same bug as in this case access to the protected member is OK. In this case, it's access to the type definition that should or should not be allowed. – shroudednight Oct 02 '12 at 19:48
1

Your program appears valid to me (well, except for Y::somethingToDo being nonsensically private). Z::f() isn't asking for access to any private names, only protected ones.

If Z::f() tried to reference Y<T>, then the compiler should err. But Z::f() is only accessing _protectedMember, which is surely allowed.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

You Y template is private and can't used in codes that are not private, like _protectedMember witch intended to be accessible from derived class, you should also declare it as protected, so its member be visible to derived classes.

as a general rule if you want your variable to be completely accessible to some scope, then its type must be completely accessible in that scope. of course your code can be useful with current design in following situation:

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

now derived classes can use _val to call doSomething but they can't call its methods or use its properties.

BigBoss
  • 6,904
  • 2
  • 23
  • 38