From: Dimitar on 3 Jun 2006 10:12 Vitaly wrote: > Hi, > > Dimitar wrote > > > template <template <class> class Search > > > class Test : public Search< Test<Search> > { > > public: > > typedef Test<Search> Parent_t; > > }; > > > > template <class Host> > > class Y { > > public: > > void Search(); > > }; > > > > class CallManager : public Test<Y> { }; > > > > > Did you actually try to create instance of CallManager? If you did not > > probably this is why it compiled. > > Yes, of course. I created the instance. It's not a problem for gcc, > for example. > > > I think Test<Y> is not correct. Y is parameterized class and you have > > to specify value for the template parameter. > > Why? What do I have? 1) class Test with template template parameter > called Search. 2) template Y. 3) template Test is instanstiated by > template Y. > > This is correct, it seems to me. Yes you are right about the template template parameter. Never mind my comment. The code compiles with VC++ 7 if it is like this: template <template <class> class Search > class Test : public Search< Test<Search> > { public: typedef Test Parent_t; }; which is funny because there is Test<Search> two lines above and it does not complain about it. Dimitar [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Michael Mehlich on 3 Jun 2006 20:19 The source code as presented below is C++ standard conformant. However, VC++ does not perform two-phase lookup as required by the C++ standard, but essentially performs all name resolution at template instantiation time. I.e., when VC++ looks up Search from within the body of an instance of Test, the method named Search from the base class is found first, shadowing the template parameter of the same name. Thus, Test<Search> becomes ill-formed. This is a problem for every C++ compiler not implementing two-phase lookup for templates. To ensure compilability of source code with different compilers, you should therefore ensure that your code does not rely on a particular behavior (two-phase lookup vs. lookup on template instantiation only) of name lookup for templates. -- Michael Vitaly wrote: > Hi, > > Dimitar wrote > > >>template <template <class> class Search > >>class Test : public Search< Test<Search> > { >>public: >> typedef Test<Search> Parent_t; >>}; >> >>template <class Host> >>class Y { >>public: >> void Search(); >>}; >> >>class CallManager : public Test<Y> { }; >> > > >>Did you actually try to create instance of CallManager? If you did not >>probably this is why it compiled. > > > Yes, of course. I created the instance. It's not a problem for gcc, > for example. > > >>I think Test<Y> is not correct. Y is parameterized class and you have >>to specify value for the template parameter. > > > Why? What do I have? 1) class Test with template template parameter > called Search. 2) template Y. 3) template Test is instanstiated by > template Y. > > This is correct, it seems to me. > > And the most interesting thing - if I rename Search memeber function of > Y to (for example) MySearch, VC++ behavior becomes the same as gcc and > comeau behavior - it compiles the code without errors and warnings. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Vladimir Marko on 4 Jun 2006 09:13
Vitaly wrote: > The code: > > template <template <class> class Search > > class Test : public Search< Test<Search> > { > public: > typedef Test<Search> Parent_t; > }; > > template <class Host> > class Y { > public: > void Search(); > }; > > class CallManager : public Test<Y> { }; > > This code successfully compiled by gcc and comeau. But if I try to > compile it with VC++ (Visual Studio 2003 or Visual Studio 2005, does no > matter) I get the follwoing error: > > > error C2975: 'Search' : invalid template argument for 'Test', expected > compile-time constant expression > h:\test\test\test\test.cpp(18) : see reference to class > template instantiation 'Test<Search>' being compiled > with > [ > Search=Y > ] It is a VC++ bug. Since Search<Test<Search> > is a _dependent_ type a name from that class cannot hide a name from the template or its enclosing scopes (see 14.6.2/4). Note, however, that if a base class that is a non-dependent type would contain the name in question the template parameter name would be hidden by the name in the base class. Thus it is preferrable to use a naming scheme which prevents such conflicts. Cheers Vladimir Marko [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |