|
-
September 24th, 2002, 08:35 AM
#1
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
-
September 24th, 2002, 08:51 AM
#2
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;
-
September 24th, 2002, 09:06 AM
#3
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.
-
September 24th, 2002, 09:22 AM
#4
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
-
September 24th, 2002, 09:33 AM
#5
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
-
September 24th, 2002, 09:33 AM
#6
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.
-
September 24th, 2002, 09:37 AM
#7
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.
-
September 24th, 2002, 09:54 AM
#8
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...
-
September 24th, 2002, 10:01 AM
#9
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.
-
September 24th, 2002, 10:03 AM
#10
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.
-
September 24th, 2002, 10:44 AM
#11
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
-
September 24th, 2002, 10:52 AM
#12
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
-
September 24th, 2002, 10:57 AM
#13
Thanks for owning and actually reading Bjarnes' book Graham!
Martin Breton
3D vision software developer and system integrator.
-
September 24th, 2002, 11:26 AM
#14
I'll finally get it delivered this week
-
September 24th, 2002, 01:19 PM
#15
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
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|