Here is my code:
#include <iostream>
template<typename T>
class RawPtr
{
protected:
T* pointee_;
public:
RawPtr() : pointee_(0) {}
RawPtr(T* pT) : pointee_(pT) {}
};
template<typename T>
class SmartPtr : public RawPtr<T>
{
public:
SmartPtr() : RawPtr<T>() {}
explicit SmartPtr(T* pT) : RawPtr<T>(pT)
{
if (pointee_ != 0)
{
std::cout << "SmartPtr(T* pT): pointee_ non-null." <<
std::endl;
}
}
};
int main()
{
double *pDoubleRaw = new double(1.0);
SmartPtr<double> pDouble(pDoubleRaw);
return 0;
}
On Linux (g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)) I get the
following compilation error:
g++ testInheritanceWithTemplates.cpp
testInheritanceWithTemplates.cpp: In constructor
`SmartPtr<T>::SmartPtr(T*)':
testInheritanceWithTemplates.cpp:27: error: `pointee_' was not
declared in this scope
On Windows, this compiles fine.
Any ideas why this doesn't work on Linux? Does the C++ standard think
that this is legal?
Regards,
Liam Herron
hi
Following is the code I tested.
#include <iostream>
template<typename T>
class RawPtr
{
protected:
T* pointee_;
public:
RawPtr() : pointee_(0) {}
RawPtr(T* pT) : pointee_(pT) {}
};
template<typename T>
class SmartPtr : public RawPtr<T>
{
public:
SmartPtr() : RawPtr<T>() {}
explicit SmartPtr(T* pT) : RawPtr<T>(pT)
{
if (RawPtr<T>::pointee_ != 0)
{
std::cout << "SmartPtr(T* pT): pointee_ non-null." <<
std::endl;
}
}
};
int main()
{
int n = 10;
SmartPtr<int> IntPtr(&n);
}
--
cch@srdgame
If anyone can point me to where this is in the 2003 C++ standard, that
would be great.
Regards,
Liam
liam_herron wrote:
>
> Here is my code:
>
> #include <iostream>
>
>
>
> template<typename T>
> class RawPtr
> {
> protected:
> T* pointee_;
>
> public:
> RawPtr() : pointee_(0) {}
> RawPtr(T* pT) : pointee_(pT) {}
> };
>
>
> template<typename T>
> class SmartPtr : public RawPtr<T>
when the compiler gets here, it will encounter a name `RawPtr<T>', and
knows that that is a template class of type<T>. when a class is
inherited from a template class, compiler will *only* find the template
base class *name* in his symbol table, and will not check its definition
detail.
> {
> public:
> SmartPtr() : RawPtr<T>() {}
> explicit SmartPtr(T* pT) : RawPtr<T>(pT)
> {
> if (pointee_ != 0)
The reason of your original code is the template specialization. when
you're defining your SmartPtr<T> here, compiler only know his base
template class name but not his details, so compiler doesn't know
SmartPtr<T> has a member pointee_ inherited from RawPtr<T>. But you
could explicitly point that out using:
if(this->pointee_ != 0)
or
if(RawPtr<T>::pointee_ != 0)
this will tell the compiler that there is a implicit rule that RawPtr<T>
has to contain a member named pointee_, and this rule will be checked
when you instantiate a SmartPtr<T> object.
> {
> std::cout << "SmartPtr(T* pT): pointee_ non-null." <<
> std::endl;
> }
> }
>
> };
>
>
> int main()
> {
> double *pDoubleRaw = new double(1.0);
> SmartPtr<double> pDouble(pDoubleRaw);
> return 0;
> }
>
>
> On Linux (g++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)) I get the
> following compilation error:
>
> g++ testInheritanceWithTemplates.cpp
> testInheritanceWithTemplates.cpp: In constructor
> `SmartPtr<T>::SmartPtr(T*)':
> testInheritanceWithTemplates.cpp:27: error: `pointee_' was not
> declared in this scope
>
>
> On Windows, this compiles fine.
>
> Any ideas why this doesn't work on Linux? Does the C++ standard think
> that this is legal?
>
> Regards,
> Liam Herron
what g++ has done here is right. because of template specialization,
compiler will not guarantee anything at complier time. think about this:
template<typename T> class base;
template<> class base<int>
{
protected:
int i;
};
template<> class base<double>
{
protected:
double foo()
{
return .0;
}
};
template<typename T>
class derived : public base<T>
{
int bar()
{
//i; is there `i'?
//foo(); or is there a foo()?
return 0;
}
};
in derived<T>::bar(), what should the compiler guarantee you? a `i' or
`foo()', or even something else? -- nothing is good, so just guarantee
nothing here. you should cry for what you want exactly and compiler will
check it for you when it instantiates that.
cheers & HTH,
Jim