• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 445
  • Last Modified:

Cannot inherit from templated class

Here is a simplified class hierarchy.  Class Main contains prototypes of 2 other classes.  Class Main::B inherits from class Main::A.  Both Main::A and Main::B are templated.  But class Main::B, which inherits from class Main::A, does not seem to have access to any variables declared in Main::A.  As such, the following code will not compile.  Can someone explain why this occurs?

class Main {
      template <typename size_type>
      class A;
      
      template <typename size_type>
      class B;
};

template <typename size_type>
class Main::A {
      protected:
      int number;
      
      public:
      A() { }
};

template <typename size_type>
class Main::B : private Main::A<size_type> {
      public:
      B() {
            number = 50; /* this won't compile */
            cout << number << endl;
      }
};

Why won't Class::B inherit the variables from Class::A?
0
chsalvia
Asked:
chsalvia
  • 6
  • 4
  • 3
  • +2
1 Solution
 
rajeev_devinCommented:
It's compiling in VC++.
0
 
AlexFMCommented:
#include "stdafx.h"

#include <iostream>
using namespace std;

class Main {
    template <typename size_type>
    class A;

    template <typename size_type>
    class B;

public:
    void Test();
};

template <typename size_type>
class Main::A {
protected:
    int number;

public:
    A() { }
};

template <typename size_type>
class Main::B : private Main::A<size_type> {
public:
    B()
    {
        number = 50;
        cout << number << endl;
    }
};

void Main::Test()
{
    B<int> b;
}

int _tmain(int argc, _TCHAR* argv[])
{
    Main m;
    m.Test();

    return 0;
}
0
 
AlexFMCommented:
Missing in my post: this test is compiled and executed successfully (VC++ 8.0).
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
chsalviaAuthor Commented:
Hmm...

it doesn't compile with gcc 4.0.  Since it appears to be syntactically correct, and it's compiling with VC++, I would guess gcc is at fault here.  

gcc will compile it if I take away the template.

0
 
chsalviaAuthor Commented:
In fact - it *STILL* won't compile even if I simplify it to only the following:

Are you sure there is nothing wrong here?  If this is syntactically correct, it seems gcc has a pretty big limitation here.

template <typename size_type>
class A {
protected:
    int number;

public:
    A() { }
};

template <typename size_type>
class B : private A<size_type> {
public:
    B()
    {
        number = 50;
        cout << number << endl;
    }
};


int main(int argc, char* argv[])
{
    return 0;
}
0
 
AlexFMCommented:
class B : private A<size_type>

Replace private with public, what is result? I am trying to guess whether gcc fails on template or private inheritance.
0
 
chsalviaAuthor Commented:
>> Replace private with public, what is result? I am trying to guess whether gcc fails on template or private inheritance.

No, that didn't compile either unfortunately.  Since it compiles on VCC, but fails on gcc, I am wondering which compiler is being ANSI compliant.  Is VCC allowing something which it shouldn't?  Or is gcc disallowing something it should allow?

0
 
AlexFMCommented:
AFAIK, VC++ 8.0 is almost 100% standard compliant.
0
 
chsalviaAuthor Commented:
Hmm...so the fault is most likely in gcc.  

It seems the problem has something to do with the fact that class B is inheriting a version of class A which depends on a template parameter.  If I change it to:

class B : private A<int>

...it works fine.
0
 
peprCommented:
Various issues with templates were always one of the "last problems" of many C++ compilers. The MS VC++ 8 is one of the best. Even the MS VC++ 7.1 is pretty good. But, for example the MS VC++ 6.0 was pretty bad with respect to the C++ norm. I cannot speak for quality of gcc or other compilers. But templates are one of the most difficult things to implement. Better to say, the other features in C++ are older in time and were implemented earlier than all details related to templates.
0
 
rstaveleyCommented:
You seem to have to qualify it thus...

template <typename size_type>
class B : public A<size_type> {
public:
        B()
        {
                A<size_type>::number = 50;
                cout << A<size_type>::number << endl;
        }
};

...or a bit less inconveniently thus...

template <typename size_type>
class B : protected A<size_type> {
        using A<size_type>::number;
public:
        B()
        {
                number = 50;
                cout << number << endl;
        }
};

...with GCC 4.1.1 otherwise, it doesn't find number in B's scope.

I've been running into this a bit recently with some home-grown policy classes, I've been developing. Notably you don't need the extra qualification with GCC 2.06 or 3.5.5, so I expect that 4.1.1 is being squaky clean in terms of standards compliance requiring it to be done this way.
0
 
chsalviaAuthor Commented:
rstaveley,

Thanks.  That seems to work fine.  I should also mention, I got it to work by prefacing each variable with this->

If you do:

template <typename size_type>
class B : public A<size_type> {
public:
        B()
        {
                this->number = 50;
                cout << this->number << endl;
        }
};

...it also works.
0
 
rstaveleyCommented:
OK, I've just done a bit of sniffing around on this. It looks like this is a new thing that the 2003 version of the ISO C++ Standard standard brought in.

Section 14.6.2, paragraph 3...

"In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member."

Does Visual C++ 8 have a command line switch to make it 2003 compliant? I'm still on 7.1. I must confess that I'm still working from the 1998 standard. The world is moving on too fast for me.
0
 
chsalviaAuthor Commented:
So it seems as though gcc is trying to be standards compliant here.
0
 
rstaveleyCommented:
Yes, it is doing the right thing.

However, I'm disappointed that the command line switch -std=c++98 doesn't allow the unaltered code to compile. According to the man page on my system, GCC 4.1.1 runs -std=gnu++98 by default, and that's 1998 with GNU extensions. There's no mention of 2003. I wonder if the man page is out of date. The man page also says that C99 is not yet fully supported, which makes me feel better about being behind the times :-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 4
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now