Re: template metaprogramming and recursive inheritance
Christof Warlich <cwarlich@gmx.de> writes:
any ideas why this does not compile?:
template <int x> struct S;
template <> struct S<0> {
S<0>(void): y(0) {}
int y;
};
template <int x> struct S: public S<x - 1> {
S<x>(void) {y++;}
};
The error that I get is:
In constructor "<x>::S()":
7: error: "y" was not declared in this scope
For my understanding, the error message is simply wrong.
Not for mine.
y is a non-dependent name. It is therefore looked up in the first
phase of the the two-phase name lookup process. In that phase,
inherited names aren't considered, because the compiler doesn't know
them.
To fix your code, make y dependant, e.g.:
template <int x>
struct S: public S<x - 1>
{
S()
{
++this->y;
}
};
This causes the name y to be resolved in the second phase, where the
specializations of S and their members are known.
Imagine instantiating
S<2> s;
This causes S<1> and S<0> to be instantiated as well due
to the recursive inheritance. Thus, y is finally provided
by the template specialization defined for S<0>, which in
turn is an indirect base of S<2>.
Could this be a compiler bug? I'm using g++ 4.1.2.
No. At the time when the compiler parses the implementation of the
base template (where y is incremented), there is no telling whether a
specialization for S<1> comes next, which doesn't provide an entity
named y to its derived classes (or an entity that can't be
incremented).
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]