CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Dec 1999
    Location
    Québec, Qc, Canada
    Posts
    26

    Explicit template instanciation

    Hi,

    In "C++ programming Language" from Bjarne Stroustrup, it is told that it's possible to instanciate (explicitly) a class template, a function template or just a member of a class template. I want to instanciate a function template of a class that is not a template itself. So, that case isn't covered in the book. I try few things as :

    Code:
    // My class that is not a template (in .h file) :
    class CVar
    {
        ...
        template< typename T >
        T* ValueGetToken( T* buf_, int buflen_ ) const;
        ...
    };
    
    // Explicit instanciation (in .cpp file) :
    template char* CVar::ValueGetToken( char*, int ) const;
    I'm always having the same linking problem. So my function isn't instanciate. Is it possible to do this? I'm compiling with Visual C++ 6 (I know it's not the reference for working with templates but I have no choice since it's the compiler my company uses).

    thanks,
    Martin

  2. #2
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Hi,

    First of all, I'm not an expert in templates (yet), so I'm not sure whether this will help you. But you can use overloading instead of explicit template instantiation.

    Code:
    T* ValueGetToken( T* buf_, int buflen_ ) const;
    
    char* ValueGetToken( char* buf_, int buflen_) const;

  3. #3
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    I don't know what the problem is, but here's how I do things:

    Code:
    class CVar
    {
        template< typename T >
        T* ValueGetToken( T* buf_, int buflen_ ) const;
    
    	char *
    	   ValueGetToken( char * yo, int ya ) const;
    };
    
    template <typename T>
    T*
     CVar::ValueGetToken( T* yo, int ya ) const
    {
    	T* toto;
    
    	return toto;
    }
    
    char *
     CVar::ValueGetToken( char * yo, int ya ) const
    {
    	char * toto;
    
    	return toto;
    }
    Hope this helps.

    Bonne chance! (moi aussi je suis débutant avec les templates! )
    Martin Breton
    3D vision software developer and system integrator.

  4. #4
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Well, proxima, you're doing exactly what I suggested in my post

    Overloading a function instead of template instantiation...

    I wonder why none of our resident gurus have replied to this post yet

  5. #5
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    First thing to note is that the instantiation given is (I think) wrong. I'm not that up on templates (especially template member functions), but I think the explicit instantiation should be:
    Code:
    char* CVar::ValueGetToken<char>( char*, int ) const
    not
    Code:
    template char* CVar::ValueGetToken( char*, int ) const
    which I think is syntactically incorrect. I also doubt if you could put it in the cpp file without "export".

    Also, I think that this sort of thing may be a non-starter with VC++6 anyway - its template handling is seriously broken around template member functions.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  6. #6
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    I guess we were typing the same thing at the exact same time, only you hit the send button just a few minutes before me! eheh

    Yeah... will the real guru please stand up? please stand up?
    Martin Breton
    3D vision software developer and system integrator.

  7. #7
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    Just an "aparté" Martin, just be careful with templates and VC++ 6.0. Template support is crappy in this version of VC. Some behaviour is NOT the intended one. I suggest you try .NET. It has resolved most of the issues we had with both STL and templates.
    Martin Breton
    3D vision software developer and system integrator.

  8. #8
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Right, that's probably it, Graham.

    The method that works is :
    Code:
    class CVar
    {
    public:
      template< typename T >
      T* ValueGetToken( T* buf_, int buflen_ ) const
      {
      }
    
       char* ValueGetToken<char>( char* buf_, int buflen_) const;    
    };
    
    char* CVar::ValueGetToken( char* buf_, int buflen_) const
    {
      printf("char *\n");
      return buf_;
    }
    I wonder though why you don't have to specify in the implementation of ValueToken that it's a template specialization ? I mean something like
    Code:
    char* CVar::ValueGetToken<char>( char* buf_, int buflen_) const
    would seem more logical...

  9. #9
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    I've talked to the office guru and here's another solution:

    Code:
    template <>
    char *
     CVar::ValueGetToken( char * yo, int ya ) const
    {
    	char * toto;
    
    	return toto;
    }
    Of course, the difference in the syntax is very slight, but the difference in the meaning is great.

    This is template specialization, whereas the former one was method overload.

    A method overload has precedence over template generated methods, thus this is a subtle difference but one that could lead to erroneous results.

    As to why template <> and not just template, we don't know. It might be "Microsoft specific".
    Martin Breton
    3D vision software developer and system integrator.

  10. #10
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    Originally posted by Yves M
    I wonder though why you don't have to specify in the implementation of ValueToken that it's a template specialization ? I mean something like
    Code:
    char* CVar::ValueGetToken<char>( char* buf_, int buflen_) const
    would seem more logical...
    Why would you need to specify the type when it is already specified in the parameter list? The compilor already knows that when it deals with char* it needs to call this method. It would be over defining the method by using redundant information.
    Martin Breton
    3D vision software developer and system integrator.

  11. #11
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    I need to do some more reading about this, cos I'm getting to the limits of my knowledge in this area. There is a fairly major difference between template functions and template classes. Now this is where my brain starts hurting, but I remember seeing somewhere something about not using the "template<>" bit at the start of a function explicit specialisation (you do use it when explicitly specialising a class).

    Ach, I need to lie down in a dark room for a while. I'll do some looking up and see if I can come up with the definitive answer (which will probably include the words "except in VC++6").
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  12. #12
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    According to Saint Bjarne, it looks like the simplest explicit specialisation would be:
    Code:
    template <> char * CVar::ValueGetToken(char* pc, int i) const
    My memory must be going........

    what was I saying?
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  13. #13
    Join Date
    May 2002
    Location
    Quebec City, Canada
    Posts
    374
    Thanks for owning and actually reading Bjarnes' book Graham!
    Martin Breton
    3D vision software developer and system integrator.

  14. #14
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    I'll finally get it delivered this week

  15. #15
    Join Date
    Dec 1999
    Location
    Québec, Qc, Canada
    Posts
    26
    Thanks for all the answers but it doesn't help. Listen! MSDN has something to tell : Linking error 2001 Look for the first Coding Problem. This is the answer.

    For those who has answer something, let's clarify some concepts related to templates.

    First, if I use a template instead of overloading, it's because I want to avoid code duplication. Template exits only for that. Saying something just one time no matter the type of an object. So instead of :

    Code:
    template< typename T >
    T* ValueGetToken( T* buf_, int buflen_ ) const;
    I could use :

    Code:
    char* ValueGetToken( char* buf_, int buflen_ ) const;
    wchar_t* ValueGetToken( wchar_t* buf_, int buflen_ ) const;
    But it's exactly what I have and what I want to replace whit my template method. Just to avoid code duplication because both methods have the same code.

    Second, someone was septical about my notation :

    Code:
    template char* CVar::ValueGetToken( char*, int ) const;
    I'm not really sure of this one because I haven't found them in Bjarne's book. But those following are legal (see Bjarne's book (3e edition) section C.13.10 p.866) :

    Code:
    template class vector<int>; // explicit instantiation of a class
    template int& vector<int>::operator[](int); // explicit instantiation of a class member
    template int convert<int,double>(double); // explicit instantiation of a function
    The 3rd one is the closest of what I try. I have a method template of a class (not a template class).

    Also, there is a difference between specialization and explicit instantiation.

    When you write code as :

    Code:
    template<> char* ValueTokenGet( char*, int );
    You are writing a specialization of ValueTokenGet for the type char. So the definition of the function would not be used for the type char, the specialization would be used.

    Explicit instantiation of a template lets you ensure that the template is define somewhere for a type T. The major advantage that I saw in this feature is that you can define the body of a function in a .cpp file. Not in the .h file. That's remove many include from the .h file (hence reducing the dependencies between files).

    Martin

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured