Nested class templates and incomplete type error

B

Belebele

The code below does not compile under g++.

There is an outer class template that contains and inner class
template. The outer class template is fully specialized for int. Then
a separate Foo class template inherits from the inner.

The compiler indicates that the inner class is incomplete when used as
the base class of the inner class template. Why?

-------------------------------------------------------------------
template <typename X> struct Outer {

template <typename Y> struct Inner {};

};

template <> struct Outer<int> { // If this full specialization is
removed, the compilation succeeds.

template <typename Y> struct Inner {};

};

template <typename T>
struct Foo: Outer<T>::Inner<T> {};

int main()
{
Foo<int> o;
return 0;
}
-------------------------------------------------------------------

Interestingly, if I remove the full specialization, the compilation
succeeds, to add to my confusion.

Thanks
 
V

Victor Bazarov

Belebele said:
The code below does not compile under g++.

There is an outer class template that contains and inner class
template. The outer class template is fully specialized for int. Then
a separate Foo class template inherits from the inner.

The compiler indicates that the inner class is incomplete when used as
the base class of the inner class template. Why?

-------------------------------------------------------------------
template <typename X> struct Outer {

template <typename Y> struct Inner {};

};

template <> struct Outer<int> { // If this full specialization is
removed, the compilation succeeds.

template <typename Y> struct Inner {};

};

template <typename T>
struct Foo: Outer<T>::Inner<T> {};

Try

template <typename T>
int main()
{
Foo<int> o;
return 0;
}

V
 
V

Victor Bazarov

Belebele said:
Right on the money, as always. What's the issue here?

The compiler needs help determining that 'Inner' member of
'Outer<T>' is a template and that the meaning of the '<' after
it is the beginning of the template argument list and not the
comparison operator.

V
 
B

Belebele

The compiler needs help determining that 'Inner' member of
'Outer<T>' is a template and that the meaning of the '<' after
it is the beginning of the template argument list and not the
comparison operator.

Is there a legal construct that makes the use of the Inner class
template ambiguous if the "template" word is not used is this context?
 
V

Victor Bazarov

Belebele said:
Is there a legal construct that makes the use of the Inner class
template ambiguous if the "template" word is not used is this context?

No, I don't believe there is. But that's the whole point. The C++
compiler cannot pick the meaning of the syntax based on its validity.

What if your 'Outer' specialisation for this particular 'T' would have
a member 'Inner' that is not a template, but instead, say, a static
constant of type 'size_t'? The expression 'Outer<T>::Inner < blah'
would be a valid expression (in some other context). The compiler
needs a nudge from you to help it interpret the _intention_. Don't
put the burden of guessing what your intention might have been onto
the poor compiler, it's already got its hands full.

But then again, I am not a compiler writer, nor am I formally educated
in computer language theory, so take whatever I say with a fistful of
salt.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top