portected access: template derivation vs. class derivation

Discussion in 'C++' started by Steven T. Hatton, Aug 19, 2004.

  1. In the following code, the class B will not compile if the function da is
    uncommented. I took exactly the same code, and turned it into templates.
    Never used the template parameter in anything but the baseclass name in the
    derived class, and the code compiles without any complaints about protected
    access. Why? What is different about the templated code?

    class A{
    public:
    A(const int& x_=0): x(x_){}
    protected:
    int x;
    };

    class B: public A{
    public:
    B(const int& x_=0): A(x_){}
    /*
    B& da(const int& da_)
    {
    this->a.x += da_; // error: protected access
    return *this;
    }
    */
    protected:
    A a;
    };

    /*Same as above but with templates*/
    template<typename T>
    class AT{
    public:
    AT(const int& x_=0): x(x_){}
    protected:
    int x;
    };

    template<typename T>
    class BT: public AT<T>{
    public:
    BT(const int& x_=0): AT<T>(x_){}

    BT& da(const int& da_)
    {
    this->a.x += da_; // works fine
    return *this;
    }

    protected:
    AT<T> a;
    };

    --
    STH
    Hatton's Law: "There is only One inviolable Law"
    KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
    Mozilla: http://www.mozilla.org
     
    Steven T. Hatton, Aug 19, 2004
    #1
    1. Advertising

  2. Steven T. Hatton wrote:
    > In the following code, the class B will not compile if the function da is
    > uncommented. I took exactly the same code, and turned it into templates.
    > Never used the template parameter in anything but the baseclass name in the
    > derived class, and the code compiles without any complaints about protected
    > access. Why? What is different about the templated code?


    The templated code is not really "compiled" unless you attempt to
    instantiate the template. Did you? Where is the rest of the code?
    Was there anything else? If there wasn't, then all the compiler did
    for your templates was checking the syntax. Names were not resolved,
    access rights weren't checked, etc.

    >
    > class A{
    > public:
    > A(const int& x_=0): x(x_){}
    > protected:
    > int x;
    > };
    >
    > class B: public A{
    > public:
    > B(const int& x_=0): A(x_){}
    > /*
    > B& da(const int& da_)
    > {
    > this->a.x += da_; // error: protected access
    > return *this;
    > }
    > */
    > protected:
    > A a;
    > };
    >
    > /*Same as above but with templates*/
    > template<typename T>
    > class AT{
    > public:
    > AT(const int& x_=0): x(x_){}
    > protected:
    > int x;
    > };
    >
    > template<typename T>
    > class BT: public AT<T>{
    > public:
    > BT(const int& x_=0): AT<T>(x_){}
    >
    > BT& da(const int& da_)
    > {
    > this->a.x += da_; // works fine
    > return *this;
    > }
    >
    > protected:
    > AT<T> a;
    > };
    >


    V
     
    Victor Bazarov, Aug 19, 2004
    #2
    1. Advertising

  3. Steven T. Hatton

    Kai-Uwe Bux Guest

    Steven T. Hatton wrote:

    > In the following code, the class B will not compile if the function da is
    > uncommented. I took exactly the same code, and turned it into templates.
    > Never used the template parameter in anything but the baseclass name in
    > the derived class, and the code compiles without any complaints about
    > protected
    > access. Why? What is different about the templated code?
    >
    > class A{
    > public:
    > A(const int& x_=0): x(x_){}
    > protected:
    > int x;
    > };
    >
    > class B: public A{
    > public:
    > B(const int& x_=0): A(x_){}
    > /*
    > B& da(const int& da_)
    > {
    > this->a.x += da_; // error: protected access
    > return *this;
    > }
    > */
    > protected:
    > A a;
    > };
    >
    > /*Same as above but with templates*/
    > template<typename T>
    > class AT{
    > public:
    > AT(const int& x_=0): x(x_){}
    > protected:
    > int x;
    > };
    >
    > template<typename T>
    > class BT: public AT<T>{
    > public:
    > BT(const int& x_=0): AT<T>(x_){}
    >
    > BT& da(const int& da_)
    > {
    > this->a.x += da_; // works fine
    > return *this;
    > }
    >
    > protected:
    > AT<T> a;
    > };
    >


    Hi,


    did you actually instantiate the template in main(), or did you just
    compile this file as a compilation unit? In the later case, it would be
    unwise for the compiler to complain: If this template is used as part of a
    bigger programm, some other part might provide a specialization for AT<>
    where the member x is not protected. For those types, BT<> should not cause
    any troubles at all. Beware that the interface of AT<T> may depend on T.

    Rest assured, you will see tons of inscrutable error messages when you
    actually instantiate the template so that access violations happen.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Aug 19, 2004
    #3
  4. "Steven T. Hatton" <> wrote in message
    news:...
    > In the following code, the class B will not compile if the function

    da is
    > uncommented. I took exactly the same code, and turned it into

    templates.
    > Never used the template parameter in anything but the baseclass name

    in the
    > derived class, and the code compiles without any complaints about

    protected
    > access. Why? What is different about the templated code?


    Try compiling your code with this main function:

    int main()
    {
    BT<int> b;
    b.da(int());
    }

    You should get the same error. The reason the templated version
    compiles in your original that dependent names (such as this->a)
    aren't looked up until instantiation, and that no instantation occurs
    in your example.

    Jonathan
     
    Jonathan Turkanis, Aug 19, 2004
    #4
  5. Jonathan Turkanis wrote:
    > "Victor Bazarov" <> wrote in message
    > news:SS7Vc.111$09.us.to.verio.net...
    >
    >>Steven T. Hatton wrote:

    >
    >
    >
    >>The templated code is not really "compiled" unless you attempt to
    >>instantiate the template. Did you?

    >
    >
    > So is the dependent/non-dependent distinction a red herring here?


    I am not sure I understand the question. Could you rephrase it?

    V
     
    Victor Bazarov, Aug 19, 2004
    #5
  6. Victor Bazarov wrote:

    > Steven T. Hatton wrote:
    >> In the following code, the class B will not compile if the function da is
    >> uncommented. I took exactly the same code, and turned it into templates.
    >> Never used the template parameter in anything but the baseclass name in
    >> the derived class, and the code compiles without any complaints about
    >> protected
    >> access. Why? What is different about the templated code?

    >
    > The templated code is not really "compiled" unless you attempt to
    > instantiate the template. Did you? Where is the rest of the code?
    > Was there anything else? If there wasn't, then all the compiler did
    > for your templates was checking the syntax. Names were not resolved,
    > access rights weren't checked, etc.


    Yes, but your question gave me an idea I hadn't tried. I hadn't actually
    invoke any functions on the template. When I did, the compiler rejected it.

    int main() {
    BT<int> bt(5);
    bt.da(1); // comment this out and it compiles
    }

    g++ -omain2 main2.cc
    main2.cc: In member function `BT<T>& BT<T>::da(const int&) [with T = int]':
    main2.cc:51: instantiated from here
    main2.cc:30: error: `int AT<int>::x' is protected
    main2.cc:40: error: within this context

    --
    STH
    Hatton's Law: "There is only One inviolable Law"
    KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
    Mozilla: http://www.mozilla.org
     
    Steven T. Hatton, Aug 19, 2004
    #6
  7. "Victor Bazarov" <> wrote in message
    news:SS7Vc.111$09.us.to.verio.net...
    > Steven T. Hatton wrote:



    > The templated code is not really "compiled" unless you attempt to
    > instantiate the template. Did you?


    So is the dependent/non-dependent distinction a red herring here?

    > Where is the rest of the code?
    > Was there anything else? If there wasn't, then all the compiler did
    > for your templates was checking the syntax. Names were not

    resolved,
    > access rights weren't checked, etc.


    Jonathan
     
    Jonathan Turkanis, Aug 19, 2004
    #7
  8. "Victor Bazarov" <> wrote in message
    news:928Vc.114$09.us.to.verio.net...
    > Jonathan Turkanis wrote:


    > > So is the dependent/non-dependent distinction a red herring here?

    >
    > I am not sure I understand the question. Could you rephrase it?


    Yes. I thought at first the reason access was not being checked was
    that in the line

    this->a.x += da_

    the name a is qualified. But I see that Comeau compiles the code
    wuthout the 'this->', as long as the template is not instantiated.

    Jonathan
     
    Jonathan Turkanis, Aug 19, 2004
    #8
  9. Steven T. Hatton wrote:
    > Victor Bazarov wrote:
    >
    >
    >>Steven T. Hatton wrote:
    >>
    >>>In the following code, the class B will not compile if the function da is
    >>>uncommented. I took exactly the same code, and turned it into templates.
    >>>Never used the template parameter in anything but the baseclass name in
    >>>the derived class, and the code compiles without any complaints about
    >>>protected
    >>>access. Why? What is different about the templated code?

    >>
    >>The templated code is not really "compiled" unless you attempt to
    >>instantiate the template. Did you? Where is the rest of the code?
    >>Was there anything else? If there wasn't, then all the compiler did
    >>for your templates was checking the syntax. Names were not resolved,
    >>access rights weren't checked, etc.

    >
    >
    > Yes, but your question gave me an idea I hadn't tried. I hadn't actually
    > invoke any functions on the template. When I did, the compiler rejected it.
    >
    > int main() {
    > BT<int> bt(5);
    > bt.da(1); // comment this out and it compiles
    > }


    Right. Instantiating a class template is not the same as instantiating
    a member of a class template. If you don't call the function, it won't
    be instantiated, and will not really be compiled (names resolved, access
    checked, etc). So, to make sure a member of a template class is correct,
    you got to try to use that member.

    V
     
    Victor Bazarov, Aug 19, 2004
    #9
  10. Jonathan Turkanis wrote:
    > "Victor Bazarov" <> wrote in message
    > news:928Vc.114$09.us.to.verio.net...
    >
    >>Jonathan Turkanis wrote:

    >
    >
    >>>So is the dependent/non-dependent distinction a red herring here?

    >>
    >>I am not sure I understand the question. Could you rephrase it?

    >
    >
    > Yes. I thought at first the reason access was not being checked was
    > that in the line
    >
    > this->a.x += da_
    >
    > the name a is qualified. But I see that Comeau compiles the code
    > wuthout the 'this->', as long as the template is not instantiated.


    Aha. So, dependent/non-dependent distinction is not a red herring,
    then, right?

    V
     
    Victor Bazarov, Aug 19, 2004
    #10
  11. "Victor Bazarov" <> wrote in message
    news:ag8Vc.118$09.us.to.verio.net...
    > Jonathan Turkanis wrote:
    > > "Victor Bazarov" <> wrote in message
    > > news:928Vc.114$09.us.to.verio.net...


    > >>Jonathan Turkanis wrote:


    > >>>So is the dependent/non-dependent distinction a red herring here?


    > > Yes. I thought at first the reason access was not being checked

    was
    > > that in the line
    > >
    > > this->a.x += da_
    > >
    > > the name a is qualified. But I see that Comeau compiles the code
    > > wuthout the 'this->', as long as the template is not instantiated.

    >
    > Aha. So, dependent/non-dependent distinction is not a red herring,
    > then, right?


    Comeau behaves the same with and without the qualification (which
    makes sense, since I don't think the meaning of 'a' can change
    depending on the template parameter T); that's why I said the
    distinction was a red herring.

    Jonathan
     
    Jonathan Turkanis, Aug 19, 2004
    #11
  12. Jonathan Turkanis wrote:
    > "Victor Bazarov" <> wrote in message
    > news:ag8Vc.118$09.us.to.verio.net...
    >
    >>Jonathan Turkanis wrote:
    >>
    >>>"Victor Bazarov" <> wrote in message
    >>>news:928Vc.114$09.us.to.verio.net...

    >
    >
    >>>>Jonathan Turkanis wrote:

    >
    >
    >>>>>So is the dependent/non-dependent distinction a red herring here?

    >
    >
    >>>Yes. I thought at first the reason access was not being checked

    >
    > was
    >
    >>>that in the line
    >>>
    >>> this->a.x += da_
    >>>
    >>>the name a is qualified. But I see that Comeau compiles the code
    >>>wuthout the 'this->', as long as the template is not instantiated.

    >>
    >>Aha. So, dependent/non-dependent distinction is not a red herring,
    >>then, right?

    >
    >
    > Comeau behaves the same with and without the qualification (which
    > makes sense, since I don't think the meaning of 'a' can change
    > depending on the template parameter T); that's why I said the
    > distinction was a red herring.



    OK, how about this:
    --------------------------------
    template<typename T>
    class AT{
    public:
    AT(const int& x_=0): x(x_){}
    protected:
    int x;
    };

    template<typename T>
    class BT: public AT<T>{
    public:
    BT(const int& x_=0): AT<T>(x_){}

    BT& da(const int& da_)
    {
    a.x += da_;
    return *this;
    }

    protected:
    AT<T> a;
    };

    template<> class AT<int> {
    public:
    AT(int = 0) : x(0) {}
    int x; /// Oops -- forgot 'protected'
    };

    int main() {
    BT<double> btd;
    btd.da(42); // error -- cannot access protected

    BT<int> bti;
    bti.da(42); // fine
    }
    ------------------------------------------------
     
    Victor Bazarov, Aug 19, 2004
    #12
  13. "Victor Bazarov" <> wrote in message
    news:VS8Vc.120$09.us.to.verio.net...
    > Jonathan Turkanis wrote:
    > > "Victor Bazarov" <> wrote in message
    > > news:ag8Vc.118$09.us.to.verio.net...
    > >
    > >>Jonathan Turkanis wrote:
    > >>
    > >>>"Victor Bazarov" <> wrote in message
    > >>>news:928Vc.114$09.us.to.verio.net...

    > >
    > >
    > >>>>Jonathan Turkanis wrote:

    > >
    > >
    > >>>>>So is the dependent/non-dependent distinction a red herring

    here?
    > >
    > >
    > >>>Yes. I thought at first the reason access was not being checked

    > >
    > > was
    > >
    > >>>that in the line
    > >>>
    > >>> this->a.x += da_
    > >>>
    > >>>the name a is qualified. But I see that Comeau compiles the code
    > >>>wuthout the 'this->', as long as the template is not

    instantiated.
    > >>
    > >>Aha. So, dependent/non-dependent distinction is not a red

    herring,
    > >>then, right?

    > >
    > >
    > > Comeau behaves the same with and without the qualification (which
    > > makes sense, since I don't think the meaning of 'a' can change
    > > depending on the template parameter T); that's why I said the
    > > distinction was a red herring.

    >
    >
    > OK, how about this:
    > --------------------------------
    > template<typename T>
    > class AT{
    > public:
    > AT(const int& x_=0): x(x_){}
    > protected:
    > int x;
    > };
    >
    > template<typename T>
    > class BT: public AT<T>{
    > public:
    > BT(const int& x_=0): AT<T>(x_){}
    >
    > BT& da(const int& da_)
    > {
    > a.x += da_;
    > return *this;
    > }
    >
    > protected:
    > AT<T> a;
    > };
    >
    > template<> class AT<int> {
    > public:
    > AT(int = 0) : x(0) {}
    > int x; /// Oops -- forgot 'protected'
    > };
    >
    > int main() {
    > BT<double> btd;
    > btd.da(42); // error -- cannot access protected
    >
    > BT<int> bti;
    > bti.da(42); // fine
    > }
    > ------------------------------------------------


    Good. This shows why the access check has to be delayed, independent
    of whether a is qualified.

    Jonathan
     
    Jonathan Turkanis, Aug 20, 2004
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. christopher diggins
    Replies:
    16
    Views:
    756
    Pete Becker
    May 4, 2005
  2. maadhuu
    Replies:
    3
    Views:
    4,101
    Alf P. Steinbach
    May 17, 2005
  3. Pierre Rouleau
    Replies:
    2
    Views:
    389
    Pierre Rouleau
    Apr 25, 2005
  4. Massimo Soricetti
    Replies:
    6
    Views:
    473
    Daniel T.
    Feb 2, 2006
  5. A L
    Replies:
    1
    Views:
    511
    Alf P. Steinbach /Usenet
    Aug 25, 2010
Loading...

Share This Page