Thread: Protected Members and Templated Inheritance

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    5

    Protected Members and Templated Inheritance

    Hi all,

    I am a bit confused about the following piece of code (as a reduced part of an other problem, also related to templates):

    Code:
    template< const int A >
    class Base
    {
    public:
      inline float getP() { return p; }
    protected:
      float p;
    };
    
    template< const int B >
    class Child : public Base< B >
    {
      void member() {
        //this->p = 5.f;
        p = 5.f;
      }
    };
    
    
    
    int main () {
      Child<4> myChild;
      myChild.getP();
      
      return 0;  
    }

    When I use the inheritance
    Code:
    template< const int B >
    class Child : public Base< B > {/* ... */};
    I am not allowed[1] to enter p without "this->":
    template.cpp: In member function ‘void Child<B>::member()’:
    template.cpp:15:5: error: ‘p’ was not declared in this scope

    If I inherit via a specialization like
    Code:
     class Child : public Base< 4 > {/* ... */};
    everything works out as normal.


    Is there any explanation for this behaviour?
    Do other compilers create the same error?


    More Details:
    • [1] compiled with:
      Code:
      $ g++ -Wall template.cpp
      $ g++ --version
         g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2


    Chers and thanks a lot,
    Axl

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Axl
    Is there any explanation for this behaviour?
    Do other compilers create the same error?
    Read the answer to this FAQ: Why am I getting errors when my template-derived-class uses a member it inherits from its template-base-class?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    5
    Thank you!

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    5
    Ok, I expanded my problem a bit and found a solution for it.
    The next problem was calling inherited member functions with templates.

    That's my solution (found in the library "loki"):


    Code:
    template< const int A >
    class Base
    {
    public:
      template< class C>
      C getP() { return static_cast<C>(p); }
    protected:
      float p;
    };
    
    template< const int B >
    class Child : public Base< B >
    {
    public:
      void member() {
        Base<B>::p = 5.f;
        // this crashes with:
        //    error: expected primary-expression before ‘double’
        //Base<B>::getP<double>();
        
        // this crashes with:
        //    error: no matching function for call to ‘Child<4>::getP()’
        //Base<B>::getP();
        
        // thats how to overcome the issue:
        Base<B>::template getP<double>();
      }
    };
    
    
    
    int main () {
      Child<4> myChild;
      myChild.member();
      
      return 0;  
    }


    Axl

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I believe this->getP<double>() should work as well.
    Similarly, this->p should work as well.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Sep 2011
    Posts
    5
    Quote Originally Posted by Elysia View Post
    I believe this->getP<double>() should work as well.
    Similarly, this->p should work as well.
    Sure, this->p works without any harm.

    But you get in trouble with this->getP<double>() Just try it

    Code:
    g++ -Wall template.cpp
    template.cpp: In member function ‘void Child<B>::member()’:
    template.cpp:29:16: error: expected primary-expression before ‘double’
    template.cpp:29:16: error: expected ‘;’ before ‘double’

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Yes, it is another issue with dependent names. The compiler doesn't know what getP is. It trusts you that it is defined in the base class. However, since it doesn't know that method is a template as well, it must assume that the < symbol is less-than operator. Again, you need to explicitly tell it that it is not the case.

    Code:
    this->template getP<double>();
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Accessing protected class members
    By Korhedron in forum C++ Programming
    Replies: 6
    Last Post: 07-29-2010, 08:12 AM
  2. base class protected members inaccessible
    By Elkvis in forum C++ Programming
    Replies: 7
    Last Post: 05-12-2010, 07:19 PM
  3. Access to members of protected base class
    By DL1 in forum C++ Programming
    Replies: 13
    Last Post: 07-20-2009, 10:30 AM
  4. problem with protected members
    By edwrodrig in forum C++ Programming
    Replies: 9
    Last Post: 01-16-2008, 12:32 PM
  5. Protected Inheritance
    By golfinguy4 in forum C++ Programming
    Replies: 8
    Last Post: 12-27-2002, 10:56 AM