   Templates and GCC
  Hi all:I'm starting to do some tests with Xcode and iPhone, and I've encountered a problem with templates. This compiles in Visual C++ 2008, but not with Xcode:class CTest;template < class T >void test( ) {    CTest *t;    t->test( );}I know that this example is really dumb, but the thing is that I don't have to include 'CTest' class in every source file, just in those that are interested in 'test( )' function.I read a while ago in some book that this... technique has a name. I'm not sure but, can it be lazy template evaluation? I can't find anything in Google...And someone knows how can I compile this piece of code with Xcode?I made the test with the Comeau web compiler and it failed, but if I DON'T use the flag '-tused', it compiles fine.Thanks a lot in advance,Carlos   
  What are you trying to do? Are you sure you mean to do:class CTest;template < class T >void test( ) {    CTest *t;    t->test( );}Don't you mean:class CTest;template < class T >void test( ) {    T *t;t->test( );}Or:template < class T >void test( T *t ) {t->test( );}...?(By the way, why isn't *t initialized? If this code snippet is literal, you are de-referencing a NULL point when you call t->test(), and it will crash or result in unexpected behavior)If you are trying to do Template specialization, it should be:#include "CTest.h"template <>void test<CTest>(CTest *param) {    param->test();}As for pre-declarations of CTest, as soon as a source file calls a member or a function of that class, it must have the full declaration. So because your function calls CTest::test(), that function needs the full declaration of CTest, and not just the pre-declaration, so it can properly dereference the function. The compiler should choke on that.[Edit:] Fixed some awkward wording.[Edited by - Servant of the Lord on October 7, 2010 3:00:01 PM];  Thanks for your answer, but I think I didn't exposed my problem quite right.I'm aware of all the things you have pointed out. I think the example was too simple. Maybe I can clarify it:// another_class.h file:class CAClass;class CAnotherClass {public:  // Blah blah  template < class T >  T doSomething( CAClass *c ) {    return c->getAs< T >( );  }};// a_class.hclass CAClass {public:  // Whatever};Then imagine I have 10 source files ( .cpp ) which include 'another_class.h', but just one of these files calls the 'doSomething' method, so I just need to include 'a_class.h' inside this one.I think it makes sense ( and I swear, I read about this 'technique' somewhere, but I can't remember where... ), because the 9 files which doesn't use the 'doSomething' method doesn't cares about the _definition_ of CAClass, just the declaration. That's why I find normal that Visual C++ 2008 compiles the code.I don't know if I can explain me better. I had to learn english in my childhood =/Thanks for your help,Carlos   ;  Your english is flawless - your post reads as if you're a native speaker. Unfortunately, I can't help you with your problem (I'm not familiar with that topic). A quick google brings up this, which may be what you are looking for. Otherwise, hopefully someone more knowledgable on the topic will come along to help you. [smile]   ;  The problem is your code is invalid and the Microsoft C++ compiler accepts it in error.The class definition must be in scope when the function is called.  Yeah, two-phase name lookup means it is not an error at template definition time, but at template instantiation time it is.  G++ is correct.  Visual C++ is nonconformant.The solution is to make sure your CTest class definition is in scope.  No shortcuts.   ;  I'm guessing it'll work if CTest is a template argument, instead of relying on the forward declaration  template <class T, class CTest>  T doSomething( CTest *c ) {//<-- confusing code - we're talking about the template param, not the actual class called CTest    return c->getAs< T >( );  };Quote:Your english is flawless - your post reads as if you're a native speaker. Unfortunately, I can't help you with your problem (I'm not familiar with that topic). A quick google brings up this, which may be what you are looking for. Otherwise, hopefully someone more knowledgable on the topic will come along to help you.Haha, thank you. I took a quick look at the link but I have to read it more thorougly to understand it =)Quote:The class definition must be in scope when the function is called. Yeah, two-phase name lookup means it is not an error at template definition time, but at template instantiation time it is. G++ is correct. Visual C++ is nonconformant.Again, I think I'm not explaining myself quite well, or I'm not understanding you =/I totally agree with what you said. The point I'm trying to show here is that I DON'T call the method 'doSomething' in a source file and the GCC compiler complains about that. To clarify, I'm not using the method 'doSomething' and the compiler tells me that there is no DEFINITION of CAClass, but as I see it, it doesn't needs the definition, because it won't be used in this module.If I'm misunderstanding your answer, I'm sorry =)Quote:I'm guessing it'll work if CTest is a template argument, instead of relying on the forward declarationThat's a good idea, thank you. I'd prefer not having to do this, because I really don't want anything else than a pointer to one kind of class.Anyways, I'd like to be conformant with C++ standard as much as I can, so if GCC behavior is the correct one, I'll pleasure him and end of story =)Thanks for all your help,Carlos   ;Quote:Original post by MChizI'd prefer not having to do this, because I really don't want anything else than a pointer to one kind of class.There's a few ways you can add this in, one is to use a static_cast, like this:  template <class T, class Y>  T doSomething( Y*c ) {    (void)static_cast<CTest*>((Y*)0);//ensure Y is derived from CTest.    //^ The "(void)" cast stops the compiler warning about this seemingly "useless" line.    return c->getAs< T >( );  };Quote:There's a few ways you can add this in, one is to use a static_cast, like this:Hey, good idea. I'll try that. Thank you again.By the way, I have found this link where it mentions that the behavior I'm expecting is correct:Link It is mentioned in the first sentences of the 'Automatic Instantiation' paragraph. Am I misunderstanding all this subject?I forgot to add that I tried to compile in CodeWarrior for Wii the same code that is failing to compile in GCC and it went well, just like in Visual C++ 2008.Man, this one is driving me crazy...Carlos   ;  I think GCC will try to evaluate all templates regardless if they are used or not. That is probably your problem.I know I've had templated code that has been completely bonkers compile just fine in VC2008, since it wasn't actually called. But GCC wouldn't have it at all.