Re: Problem with derived templates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Axel;-)
> 
> 
> template <int N> class TBase {
> public:
>   int     Array[N];
>   int     fb1() { return Array[0]; };
> };        // everything is OK in TBase
> 
> template <int NN> class TDerived : public TBase<NN> {
>   int     UU;
> public:
>   int     fc2() { return Array[0]; };  // error: 'Array' was not declared in this scope
>   int     fc3() { return UU; };        // OK
>   int     fc4() { return fb1(); };     // error: .... 'fb1' must be available
> };
> 
> int main() {
>   TDerived<10> Derived;
>   Derived.Array[2] = 5;   // OK
>   Derived.UU = 1;         // correct error, because UU is private
>   Derived.fb1();          // OK
>   return 0;
> }
> 
> Why is it not possible to access the Members of the base template
> class TBase in the scope of the derived class TDerived ?
As I understood the C++-standard, the compiler is right: When the
compiler reads the definition of class TDerived, it does NOT know the
value of NN, so it does NOT know, whether TBase<NN> really has members
"Array" and "fb1". And it is possible (and absolutely legal C++-code) to
write a template specialization of TBase for some values of NN, which
does NOT have the members "Array" and "fb1".

So: You have to state explicitly the Base-class.

> 
> I can fix this by writing:
>   int     fc2() { return TBase<NN>::Array[0]; };
> but in our production code, the base class is a template with 4
> parameters and its members are used a lots of times in the derived
> classes, so changing all these does not make the code very readable.
There is also another possibility -- "using":
If you add
  using TBase<NN>::Array;
  using TBase<NN>::fb1;
in the definition of TDerived, the compiler will find "Array[0]" and
"fb1()" from the Base-class:

template <int NN> class TDerived : public TBase<NN> {
  using TBase<NN>::Array;
  using TBase<NN>::fb1;
  int     UU;
public:
  int     fc2() { return Array[0]; };  // error: 'Array' was not declared in this scope
  int     fc3() { return UU; };        // OK
  int     fc4() { return fb1(); };     // error: .... 'fb1' must be available
};
 
That will work also. However, there is one difference between both
solutions: when you have a template specialization like "template <>
class TBase<5>{};" which does NOT have the members Array and fb1:
 - my proposal with "using TBase..:" will NOT compile
 - your code (writing TBase<NN>:: at every access) will compile, as long
   as you dont call those functions (you could call however "fc3"
   without problems)

HTH,

Axel

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux