C++ Inheritance Issue - c++

I am using code::blocks, with, I believe gcc. Given the example code (this is pseudo code and may not replicate the problem):
//Assume this is in a separate header file to B
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
class TestB : public TestA
{
public:
void CallFunction(){ A = 10; Function1();}//
};
I would get similar compile errors, like:
Error: 'A' not declared in this scope.
Error: Function1() not declared in this scope.
I was under the impression that all base variables and functions were inherited to the subclass. Given the base class has a lot of functions and variables, I don't want to use the 'using' keyword as I'd have to declare it for every function and variable (to my knowledge).
Is there any way to make it so TestB explicitly or actually includes the stuff it's inheriting?
Relevant snippets below
Okay. It's not possible to include example code as it's in project, but I will quote the key snippets:
C:\Users\user\Desktop\Projects\RND2\TemplateListAdv.h|30|error: 'Size' was not declared in this scope|
The line this is on is:
if(!Array.SetToSize(Size))
The class it's in is:
template<typename TemplateItem>
class TemplateListAdv : public TemplateList<TemplateItem>
And the incriminating line from TemplateList is:
SIZE_TYPE Size; //SIZE_TYPE is unsigned long.
//SIZE_TYPE is available in all files as unsigned long.
Files go:
TemplateList.h->TemplateBasics.h->TemplateListAdv.h
No missing files from what I can see.
I will tack in, the 'using' keyword resolves it individually, but this has been bugging me as I thought inheritance was automatic.
Compiler data as requested:
"Release 10.05 rev 6283 (2010-05-27 09:09:13) gcc 4.4.1 Windows/unicode - 32 bit"

So it looks like you are getting error wite template classes inheritance, isn't it? They are a big difference comparing to non-template ones. Assuming you have code like this:
template <class T>
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ A = 10; Function1();}//
};
The issue is caused by two-phase name lookup. All members of the base TestA class are dependent names, i.e. they depend on the template argument T. This is so because you can have template specialization for TestA with totally different members, e.g.:
template <class T>
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ A = 10; Function1();}//
};
template <>
class TestA<int>
{
};
Now, there is no A and Function1 members in the TestA, so they would be unaccessible in TestB as well. In order to let compiler know that these members are indeed depende on the template argument you should write TestB like this:
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ this->A = 10; this->Function1();}//
};
This way you make compiler resolve names only during template instantiation time instead of template declaration time and it will known about base class members.
One thing to add is that there is no such issue with VC compiler, it doesn't try to parse templates until instantiation and thus don't support two-phase name lookup.

The problem that you're having about accessing base class stuff in a class template, is a FAQ item.
Rather then quoting the whole FAQ item here, I just link to it: that's your answer.
The code that you presented to illustrate the problem was unrelated, sorry. It is always a good idea to give an actual example rather than an example of what one thinks might be the problem.
Cheers & hth.,

The problem is that you are using templates, and the base class is a 'dependent name'. That is, the template base class could be specialized and not have the Size member, the compiler just doesn't know when it compiles your class, because the Size reference is not in a dependent context.
In your particular case the easiest solution is to refer to the inherited members using this:
if(!Array.SetToSize(this->Size))
And since this is a dependent name, it should work

Are you sure that :
Size is a protected or public attribute of TemplateList ?
you're not calling if(!Array.SetToSize(Size)) from a static method ?

The question is really bad, and you might want to improve on that. Anyway, my crystal ball tells me that Size is defined in a base template, and that because the identifier Size is not dependent lookup is not going into the base template and the compiler not seeing it. Add a this-> before Size and you should be set.

When interpreting a template member function, the compiler must (following the standard) decide for each symbol if it is dependent on the template parameter. If it is dependent on it, then it'll only be resolved when the template is instantiated. However, he must resolve it at this moment.
In your case, the compiler think that A and Function1 don't depend on the template parameter and should thus be resolvable just after the parse. You just have to make it depend on the template parameter by using this->A and this->Function1
So, you should have something like that.
template < typename T >
class Base
{
protected:
int A;
public:
void Function1() { A = 0; }
};
template < typename T >
class Derived : public Base< T >
{
public:
void CallFunction1() {
this->A = 10;
this->Function1();
}
};

Related

Inheritance of template classes in C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Inherited template classes don't have access to the base class
I'm experiencing problems with templates and inheritance. Simply, I have a template class which I want another template class to inherit from. I don't understand why members of base class are not visible within deriving class? Though without using templates everything works as expected. For example:
template <typename T>
class Foo
{
public:
T x;
T y;
void doX(){ x = x+1; }
void doY(){y++;}
protected:
T a;
T b;
void doA(){a++;}
};
template <typename T>
class Bar : public Foo<T>
{
public:
void doX(){x++; y++;} // ERROR
void doY(){x++; y++;} // ERROR
void doA(){a++;b++;} // ERROR
};
These variables are dependent names (read The Dreaded Two-Phase Name Lookup for details), so you need to use this as:
void doX(){ this->x++; this->y++; }
Usually this-> is not required as it is implicit. But here it is required. Actually explicit this-> tells the compiler to look up the name in the second phase when the base class is instantiated, as this case uses two-phase name lookup mechanism.
Or you could qualify them with base class as:
template <typename T>
class Bar : public Foo<T>
{
typedef Foo<T> base; //add this friendly typedef!
public:
void doX(){ base::x++; base::y++;}
//...
};
In this case, the fact that the names cannot be looked-up untill base (which is a typedef of Foo<T>) is instantiated, becomes more obvious (to humans eyes) in my opinion.
If the base class depends on a template parameter, then its members aren't directly available in the derived class definition. Until the template is instantiated, the compiler doesn't know what the base class will contain, and so it won't look up any names from there.
You can force it to treat the names as members by qualifying them:
void doX(){this->x++; Foo<T>::y++;} // OK: both forms specify that it's a member
Write this->x, this->y instead of x, y in derived class functions.
Try referring to the variables using the base class scope:
Foo<T>::x
or use this
this->x

C++ template class specialization: why do common methods need to be re-implemented

In the sample:
#include <iostream>
using namespace std;
class B
{
public:
virtual void pvf() = 0;
};
template <class T>
class D : public B
{
public:
D(){}
virtual void pvf() {}
private:
string data;
};
template <>
class D<bool> : public B
{
public:
D();
virtual void pvf(){ cout << "bool type" << endl; }
};
int main()
{
D<int> d1;
D<bool> d2;
}
I get the following error:
test.cpp:(.text+0x1c): undefined reference to `D<bool>::D()'
Note that the reason I don't just specialize the D() by itself is I want to eliminate the need for string D<T>::data in the D<bool> case.
Why do I need to re-implement D() in D<bool>? Seems like there should be a way for me to tell the compiler to use the version from D<T>.
Is there any way to do a simple specialization like this without having to re-implement methods?
Each specialisation of a class template gives a different class - they do not share any members with each other. Since you've explicitly specialised the entire class, you don't get any of the members from the template, and must implement them all.
You can explicitly specialise individual members, rather than the entire class:
template <> void D<bool>::pvf(){ cout << "bool type" << endl; }
Then D<bool> will still contain all the members of the class template that you haven't explicitly specialised, including the default constructor.
No, there is not.
Specialization is behaving very differently than inheritence. It has no connection to the generic template version.
When you use/instantiate a template, the compiler will create a new type name, and then look for how this type is defined. When it finds a specialization, then it takes that as the definition for the new type. When it does not, it takes the generic template and instantiates it.
Therefore they have no connection, and you are just writing an entirely new class, just with a special name for the compiler to find in case of someone using/instantiating the template to find it under that name.
The problem is your erroneous assumption that there is anything common between D<A> and D<B>. Template instances are types, and two different instances are two different types, end of story. It only so happens that instances of the same template have formally similar code, but with specialization you can define any type you like. In short, every type that you define explicitly is entirely independent, and there is no commonality across specialized template instances, even if they happen to have the same name.
For example:
template <typename T> struct Foo
{
T & r;
const T t;
void gobble(const T &);
Foo(T *);
};
template <> struct Foo<int>
{
std::vector<char> data;
int gobble() const;
Foo(bool, int, Foo<char> &);
};
The types Foo<char> and Foo<int> have nothing to do with one another, and there is no reason why any part of one should have any use inside the other.
If you want to factor out common features, use private inheritance:
template <typename> struct D : private DImpl { /* ... */ }
You need to reimplement it because D<T> and D<bool> are totally unrelated classes (they just happen to "share the name"). That's just how templates work.
If you want the classes to share construction code, just put that code inside B::B (i.e. the same thing you do every time you want to reuse code in different branches of the same hierarchy: move the code up and let inheritance handle the rest).
Consider that D<T>::D() will be responsible for default-constructing string data, and that D<bool> doesn't have any such member. Clearly there is no way to use the same emitted code in each case.
However, if your default constructor doesn't do anything (in either version here), just omit it and allow the compiler to do the work.

how to implement Singleton in C++

This post is what I just read.
The way he implements Singleton in C++ confuses me. I got several Questions about it and here is his code:
template<typename T>
class Singleton {
public:
static T& getInstance() { //Question 1
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};
Question
I think we should put the static T& getInstance()'s definition outside of the class body, right?
He tries to make class DebugLog a singleton class, but when he inherits Singleton<DebugLog>, the DebugLog doesn't already exist, right? If right, then how can the template class Singleton instantiate an un-existent class?
1) Nope, it doesn't matter how you structure your code. Singleton isn't a class, by the way: It's a template. Since the full template definition must be visitible at any instantiation site anyway, you might as well define everything inline.
2) class DebugLog : public Singleton<DebugLog> is fine. We are not inheriting from a non-existing class; rather, we are inheriting from the class Singleton<DebugLog>. Templates can be instantiated on incomplete types. (There are several rules what you can and cannot do with such a type parameter.)
For example, template <typename T> class Foo { }; can certainly be instantiated on any type without problem. More interestingly, template <typename T> struct PointerFactory { typedef T * type; }; can be instantiated on any type, complete or not. In the present situation, the purpose of the template parameter in the CRTP is solely to inform the base class of its eventual derived type, so this is entirely fine.
It would certainly be cleaner if the function were defined outside of
the class, and make the code easier to read and to maintain. In this
case, however, the complete class is small enough that the difference
isn't very great, and of course, because we're dealing with a template,
the actual definition still has to be included in every translation unit
which uses it.
The C++ standard doesn't speak of “existence” with regards to classes (or anything
else). At the point of template instantiation, name lookup finds
DebugLog, and finds that it is a class (thus, a type). At that point,
it is an incomplete type, and there are only limited things you can do
with an incomplete type. If the class template which is instantiated
doesn't do anything that requires a complete type (and Singleton
doesn't), then there is no problem. (Note that only the class
definition is instantiated at this point; class member functions will
not be instantiated until they are used.)
I might add that there is still one important thing missing from the
code you posted: there is no definition for the declaration
Singleton::instance. You still need to add a:
template<typename T> T Singleton<T>::instance;
somewhere.
You must use a pointer to T in this case:
template<typename T>
class Singleton {
public:
static T& getInstance() {
static T * instance = NULL;
if (!instance)
instance = new T;
return *instance;
}
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};

Simple template inheritance issue C++

template <class T>
class baseclass{
protected:
T data;
public:
baseclass(){};
void setData(T d);
};
template<class T>
void baseclass<T>::setT(T d){
data = d;
}
Shown above is my base class, one protected member variable, one setter.
template <class T>
class aclass : public baseclass<T>
{
public:
aclass(T d);
};
template<class T>
aclass<T>::aclass(T d){
setData(d); <---WORKS
data = d; <---DOESN'T WORK
}
Now this is my subclass of the first. For some reason, accessing the protected member variable directly is not working though I believe it ought to. However, accessing the setter works fine. I'm a noob with C++, I'm sure I'm missing something obvious.
The reason that this doesn't work is a quirk in the way that C++ templates do name resolution. In particular, if you have a template class that inherits from another class that depends on a template type (as you're doing in this case), you cannot access the members of that base class directly without giving the compiler a hint about where to look. This is the cause of the error you're getting.
To fix this, you can rewrite your constructor as
template<class T>
aclass<T>::aclass(T d){
setData(d);
this->data = d;
}
Now that the compiler knows that data must somehow be a member of aclass<T>, it can find what it's looking for.
Interestingly, you should also be getting an error on the previous line for the same reason. I'm not sure why it decided to compile. To fix this, you can either do this:
template<class T>
aclass<T>::aclass(T d){
this->setData(d);
this->data = d;
}
Alternatively, you can add a using declaration to tell the compiler that aclass inherits the setData method from its parent class. In the class declaration, consider adding this line:
template <class T>
class aclass : public baseclass<T>
{
public:
aclass(T d);
using baseclass<T>::setData;
};
Like the this-> for data members, this trick makes it unambiguous where the name setData comes from and helps the compiler know what you're talking about.
Hope this helps!

Declaring an instance of an explicit specializtion of a template within a regular class

I can't get this to compile at all. I may not be possible but I don't know why it should not be.
class A {
template <typename T>
class B {
int test() { return 0; }
};
//template <> class B<int>; <-with this, namepace error
B<int> myB_;
};
template <> class A::B<int> {
int test() {
return 1;
}
};
As it appears the compiler complains "The explicit specialization "class A::B" must be declared before it is used."
If I try to provide the froward declaration in the commented line, the compiler complains
"The explicit specialization "B" must be declared in the namespace containing the template."
We use 2 different compilers here. This error is from IBM's "xl" compiler on AIX but I get similar errors with different verbage when compiling on our Sun systems.
It seems like a catch-22.
Obviously, this is a highly contrived, simplistic example but, it represents the problem.
I want to define a template class within a class because the template class is only relevent to the containing class. There should be no access to the template from outside the class.
Am I missing something?
You are correct. This is not possible to do (as far as I know). Your member declaration causes an implicit instantiation before the explicit specialization was declared. But how would you want to declare it? You cannot do that in class scope. Others have felt that this is an ugly restriction.
You could work around this by making the class member a pointer. This would not need to implicitly instantiate the class at that point, but rather at the point where you create the object in the end. I realize that this is an ugly work around. So better find other ways to do this.
For instance partial specializations are allowed in class scope. So you could add a dummy template parameter, then you can specialize this in the class before the member declaration. Likewise, i find this ugly, but it would not disturb things that much, I feel.
You could work around the issue by using an unnamed namespace for privacy:
namespace {
template <typename T>
class B {
int test() { return 0; }
};
template <> class B<int> {
int test() {
return 1;
}
};
}
class A {
B<int> myB_;
};
This will compile, but if A needs to be visible outside this compilation unit, you'll need more elaborate machinery (e.g., interface and factory or Pimpl).
B is not a template class and you are trying to specialize it. That is the cause for the error. You can check these two errors C2913 and C3413.
Is this what you are looking for?
class A
{
template<class T>
class B
{
inline int test()
{
return 0;
}
};
A::B<int> myB_;
};