I’ve got a question about templates in C++. Why do you need to put template class implementations in the same file as the declarations? Why can’t you just compile them like any other class? I used to have a pretty good idea why, but for the life of me I can’t remember, and none of my references are any help.
Basically, it’s because a template is just a pattern for creating an actual function. The compiler creates a new function for each type as it is needed. So the template itself doesn’t get compiled.
I figured it had something to do with that. I need to look into the specific error messages before I can get a more specific question.
Why use C++ when you can use Java?
HAHAHAHAHAHAHAHAHAHA
Why use a shovel when you have a rake?
Wow, goofy double-post on my first post, and it won’t let me edit or delete the post. Looks like i’m off to a good start!
Ah, fer chrissakes, can we stay out of Turing’s tar pit? I use C++ for some things, and will use Java where it’s appropriate. Neither language is so godawful or wonderful that there’s always a clear choice, and that’s that.
Actually, it was really funny that you asked a question about one of the ways in which C++ has a clear an unambiguous advantage over Java (parametric polymorphism through generics), and someone suggested you use Java.
I would daresay that I wouldn’t use Java if I were leery of the extremely common and also extremely silly downcasting required to simulate parametric polymorphism using subtype polymorphism in Java. And I might not want the excessive performance hit required from walking metaobject information that is required by Java to verify downcasts at runtime.
You know, things like that.
Actually, it was really funny that you asked a question about one of the ways in which C++ has a clear an unambiguous advantage over Java (parametric polymorphism through generics), and someone suggested you use Java.
I would daresay that I wouldn’t use Java if I were leery of the extremely common and also extremely silly downcasting required to simulate parametric polymorphism using subtype polymorphism in Java. And I might not want the excessive performance hit required by walking metaobject information that is required by Java to verify downcasts at runtime.
You know, things like that.
Actually, it was really funny that you asked a question about one of the ways in which C++ has a clear an unambiguous advantage over Java (parametric polymorphism through generics), and someone suggested you use Java.
I would daresay that I wouldn’t use Java because if I were leery of the extremely common and also extremely silly downcasting required to simulate parametric polymorphism using subtype polymorphism in Java. And I might not want the excessive performance hit required by walking metaobject information that is required by Java to verify downcasts at runtime.
You know, things like that.
Ultrafilter, my previous three posts were an attempt to illustrate the template mechanism. You see, template code is not true parametric polymorphism. It’s not compiled to a single function that works for all argument types, it is more like a macro that is instantiated at each type it needs to be.
Right, I understand that. That explains why you have to have the template implementation of a function in the same file as the calls made to that function. But why does compiling a file that contains only a template implementation throw an error? Is that necessary, or just the way they decided to do it?
I knew you understood it, I was just trying to make it look like the triple post was intentional.
I don’t have any problem compiling a file consisting of only:
template<class T>
T id(T x) { return x; }
using either g++ version 3.1 or Microsoft C/C++ version 12.00.8186. Could it be something else? A wierd interaction of the template and something in a header file?
Using MS Visual C++ 6.0, I had problems treating a template class, say a linked list, like a normal class. I would either have to put everything in the header file, or do the following:
TemplateList.h:
#ifndef TEMPLATE_LIST_H
#define TEMPLATE_LIST_H
// class declaration
#include “TemplateList.cpp”
#endif
TemplateList.cpp:
#ifdef TEMPLATE_LIST_H
#define TEMPLATE_LIST_CPP
// class implementation
#endif
You can compile template function definitions separately as long as they are fully specialized or only used in the same translation unit. Not fully specialized templates need to have their definitions visible when you’re calling them because the compiler will generate the code at that time.
Why can’t a non-fully specialized function (or member functions in such a class) be seperately compiled? Because the compiler doesn’t know what code to generate for calls in other modules; it can’t very well generate code for all possible combinations of template parameters…
There are ways around this limitation. The compiler could for example generate a “code template” for the function definition and rely on the linker (which knows exactly what function definitions are needed) to generate the code. But that would make the linker considerably more complex and slow down build times (there are probably other disadvantages I can’t remember right now). No compiler I know of supports this.
A word of warning: the template support in VC++ 6.0 is so horribly broken that it’s only slightly less painful to work with than poking your eyes out using pieces of broken glass. You won’t notice it for extremely simple templates like your linked list example, but trying anything even remotely sophisticated will require you to work around lots of compiler bugs and limitations. The template implementation in Visual C++ 7.0 (aka .NET) is considerably less buggy but still lacks several important features.
As you may know, the C++ Standard describes a keyword export that allows you to place template declarations in header files and definitions in the main source file. Alas, there were NO compilers with support for export until recently. But even when (or if) mainstream compilers implement export, it won’t give you true separate compilation for templates; at best it will give you the illusion of separate compilation (ie the compiler and/or linker will transparently force recompilation whenever necessary).
Isn’t it possible to explicitly instantiate template functions, allowing the functions to be compiled separately? For example…
template<class T> T max(T left, T right) { return (left > right) ? left : right; }
int max(int, int);
char max(char, char);
Or is that only for template classes?
Isn’t it possible to explicitly instantiate template functions, allowing the functions to be compiled separately? For example…
template<class T> T max(T left, T right) { return (left > right) ? left : right; }
int max(int, int);
char max(char, char);
Or is that only for template classes?
Yes - what you are thinking of is what I referred to as “fully specialized template functions” above. If you declare a fully specialized template function (or member function), the definition can be separately compiled. The recommended way to declare such functions are as follows:
template <class T> T max(T left, T right) { return (left > right) ? left : right; }
template <> int max(int, int);
template <> char max(char, char);
Note that the last two functions are fully specialized instances of the original max template rather than regular overloaded functions (the difference is subtle).