0

In the following code, I have an item in the initializer list

ExtendHelper<Extender>::Type<> 

that exactly matches a base class:

ExtendHelper<Extender>::Type<> 

But the VS2010 compiler complains: error C2614: 'Base::Type<T>::Extend<Extender>' : illegal member initialization: 'Type<Base::Type<Base::Type<Base>::ExtendHelper<Data> >::ExtendHelper<Data> >' is not a base or member.

How can this be?

struct Base { template <class T=Base> struct Type { template <class Extender> struct ExtendHelper { template <class U=ExtendHelper> struct Type : T::Type<U>, Extender { Type(typename T::Type<T> &rhs) : T::Type<U>(rhs) { } Type() {} }; }; template <class Extender> struct Extend : ExtendHelper<Extender>::Type<> { template <class C> Extend(C &rhs) : ExtendHelper<Extender>::Type<>(rhs) { } }; }; }; struct Data { }; Base::Type<Base> base; Base::Type<Base>::Extend<Data> baseWithData(base); 

Edit: note that I had to add a default constructor to ExtendHelper because the compiler wanted one, but I don't know why.

2
  • My compiler spit way more errors than yours. Commented Nov 1, 2011 at 15:39
  • I think I discovered a bug with MS VS2010 C++ compiler. Commented Nov 1, 2011 at 20:32

2 Answers 2

4

You need to specify that the nested name Type refers to a template. Literally replace all occurrences of ::Type< by ::template Type<.

(This isn't the only problem; there's another one with the constructor of ExtendHelper that I'm still trying to see through.)

Update: I think your outer Type class is missing a constructor. If you add the following two, it'll work:

template <typename U> Type(const U &) { } // needed for `Base::Type<Base>&` in the constructor initializer Type() { } // needed for `base` in the example code 
Sign up to request clarification or add additional context in comments.

Comments

1

Your example code is invalid, AFAIK. I had to apply the following changes to fix some of the errors:

--- nested.cxx.orig 2011-11-01 16:58:30.234375000 +0100 +++ nested.cxx 2011-11-01 17:00:13.781250000 +0100 @@ -9,12 +9,12 @@ struct Base template <class U=ExtendHelper> struct Type : - T::Type<U>, + T::template Type<U>, Extender { - Type(typename T::Type<T> &rhs) + Type(typename T::template Type<T> &rhs) : - T::Type<U>(rhs) + T::template Type<U>(rhs) { } Type() {} @@ -24,12 +24,12 @@ struct Base template <class Extender> struct Extend : - ExtendHelper<Extender>::Type<> + ExtendHelper<Extender>::template Type<> { template <class C> Extend(C &rhs) : - ExtendHelper<Extender>::Type<>(rhs) + ExtendHelper<Extender>::template Type<>(rhs) { } }; 

After the changes I get this:

g++ -Wextra -Wall -pedantic -std=c++98 -c nested.cxx nested.cxx: In constructor ‘Base::Type<T>::ExtendHelper<Extender>::Type<U>::Type(typename T::Type<T>&) [with U = Base::Type<Base>::ExtendHelper<Data>, Extender = Data, T = Base, typename T::Type<T> = Base::Type<Base>]’: nested.cxx:32:60: instantiated from ‘Base::Type<T>::Extend<Extender>::Extend(C&) [with C = Base::Type<Base>, Extender = Data, T = Base]’ nested.cxx:42:49: instantiated from here nested.cxx:17:44: error: no matching function for call to ‘Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type(Base::Type<Base>&)’ nested.cxx:5:5: note: candidates are: Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type(const Base::Type<Base::Type<Base>::ExtendHelper<Data> >&) nested.cxx:5:5: note: Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.