Paul Pluzhnikov wrote: > >> I am thinking: why if i will comment lines marked with '#' in the >> following >> example, all will be compiled, else will not: > > You'll get better answers if you reduce your test case (or state > that you couldn't).
I have posted complete compileable example and can not reduce it because can not detect the point of error, so I have posted all parts. I have marked probably error's line by "#" sign: public: typedef c_Second Second; typedef typename c_Second::Third Third; //#1 typedef typename c_Second::Forth Forth; //#2 >> 11.cpp:57: error: no type named 'Second' in 'class >> 11.cpp:57: error: Pxx::Puser::First<int, unsigned int>' It is really wrong error message of gcc due to "type named 'Second'" is declared in the class. My question was: why if I declare only typedef c_Second Second; all will be OK? Is it standard behaviour (unexplainable for me) or it is gcc specific error? It is important for desing of my classes. If it is error and it is error in "Second::subtype" why gcc point to "Second", not to "Second::subtype"? It is really not easy to find a cause of the error looking for "Second". *** By the way, i think we must not get any errors here, because all have been declared correctly, if we will trace compilation pass we will see the following: 1. class template Pxx::First declaration namespace Pxx{ template < class Tobj, class c_Second, class Tuint=uint > class First { public: typedef c_Second Second; typedef typename c_Second::Third Third; //#1 typedef typename c_Second::Forth Forth; //#2 here "Second" will be used as forward declaration of the class name, no sizeof(Second) needed, so we even can compile here concrete code returning references to "Second" and so on, the name can not be resolved at the point of template declaration. "typename c_Second::Third" is forward declaration of the class name, can not be resolved at the point of template declaration. 2. class template Pxx::Second declaration namespace Pxx{ template < class Tobj, class c_First, class c_Forth, class c_Third, class Tuint=uint > class Second { public: typedef c_First First; typedef c_Forth Forth; typedef c_Third Third; //derived Second typedef typename c_First::Second c_Second; here the same, "typename c_First::Second" is forward declaration of the class name, can not be resolved at the point of template declaration. 3. some classes forward declarations namespace Puser{ template <class Tobj,class Tuint> class First; template <class Tobj,class Tuint> class Second; template <class Tobj,class Tuint> class Third; template <class Tobj,class Tuint> class Forth; here the same: "First<>" and "Second<>" are forward declarations of the class name, can not be resolved at the point of template declaration. 4. class template Puser::First declaration template < class Tobj, class Tuint=uint > class First: public Pxx::First< Tobj, Second<Tobj,Tuint>, Tuint > { typedef Pxx::First< Tobj, Second<Tobj,Tuint>, Tuint > Tparent; now "typename Tparent::Second" is instantiated as "Second<Tobj,Tuint>" >> 11.cpp:57: error: no type named 'Second' in 'class >> 11.cpp:57: error: Pxx::Puser::First<int, unsigned int>' What is the problem here? Nothing. "typename Tparent::c_Second::Third" is still forward declaration of the class name, can not be resolved at the point of template Puser::First declaration, because we have no body of "Second<Tobj,Tuint>" here, only forward declaration of "Second<Tobj,Tuint>". 5. class template Puser::Second declaration template < class Tobj, class Tuint=uint > class Second: public Pxx::Second< Tobj, First<Tobj,Tuint>, Forth<Tobj,Tuint>, Third<Tobj,Tuint>, Tuint > { typedef Pxx::Second< Tobj, First<Tobj,Tuint>, Forth<Tobj,Tuint>, Third<Tobj,Tuint>, Tuint > Tparent; now "typename Tparent::First" is instantiated as "First<Tobj,Tuint>" "typename Tparent::First::Second" already _can_ be found during declaration of "Puser::Second" because we have already defined body of "First<Tobj,Tuint>" here: ("typename Tparent::Second" is instantiated as "Second<Tobj,Tuint>") so "typename Tparent::First::Second" is well defined as "Second<Tobj,Tuint>" (as itself). Beause "Second<Tobj,Tuint>" is self name, the name can be used not only as forward declaration of "Second<Tobj,Tuint>", but yet as name of "class with completely defined body", because compiler must allow "multipass" for class's types untill the class's "};" sign encountered. But in the example we do not need that, it is enough to treat the name as forward declaration of the class. We also can write in "Pxx::Second" like this //subtype of derived Second typedef typename c_First::Second::First c_Second_subtype_First; and "typename Tparent::c_Second_subtype_First" is "First<Tobj,Tuint>" (the same as "typename Tparent::First") 6. instance of Puser::First<int> using Puser::First; First<int> test; "typename Puser::First<int>::Tparent::Second" is "typename Puser::Second<int>" "typename Puser::First<int>::Tparent::Third" is "typename Puser::Second<int>::Third<int>" //#1 "typename Puser::First<int>::Tparent::Fourth" is "typename Puser::Second<int>::Fourth<int>" //#2 All completely defined. > > The error message appears to be mis-leading. > Here is what EDG parser reports: > > "junk.cc", line 57: error: incomplete type is not allowed > typedef typename c_First::Second c_Second; > ^ It is interesting why "typename c_First::Second" is incomplete? > detected during: > instantiation of class "Pxx::Second<Tobj, c_First, c_Forth, > c_Third, Tuint> [with Tobj=int, > c_First=Pxx::Puser::First<int, uint>, > c_Forth=Pxx::Puser::Forth<int, uint>, > c_Third=Pxx::Puser::Third<int, uint>, Tuint=uint]" at > line 106 > instantiation of class "Pxx::Puser::Second<Tobj, Tuint> [with > Tobj=int, Tuint=uint]" at line 14 > instantiation of class "Pxx::First<Tobj, c_Second, Tuint> [with > Tobj=int, c_Second=Pxx::Puser::Second<int, uint>, > Tuint=uint]" at line 81 > instantiation of class "Pxx::Puser::First<Tobj, Tuint> [with > Tobj=int, Tuint=uint]" at line 141 > What is "EDG parser"? -- Maksim A. Polyanin http://grizlyk1.narod.ru/cpp_new _______________________________________________ help-gplusplus mailing list help-gplusplus@gnu.org http://lists.gnu.org/mailman/listinfo/help-gplusplus