I have a function declared like so:
template
T read();
and defined like so:
template
The problem is that a function template is not a function. It's a template for creating functions as needed.
So for a template to work, the compiler intuitively needs two pieces of information: The template itself, and the type that should be substituted into it.
This is unlike a function call, which the compiler can generate as soon as it knows that the function exists. It doesn't need to know what the function does, just that it looks like void Frobnicate(int, float)
, or whatever its signature is.
When you declare the function template without defining it, you're only telling the compiler that such a template exists, but not what it looks like. That's not enough for the compiler to be able to instantiate it, it has to be able to see the full definition as well. The usual solution is to put the entire template in a header that can be included where needed.
Is their any compiler support template separate compilation?
As I know the common practice is declare and implement template functions in the header file
You need to use the export
keyword. However, I don't think G++ has proper support, so you need to include the template function's definition in the header so the translation unit can use it. This is because the <int>
'version' of the template hasn't been created, only the <typename T>
'version.'
An easy way is to #include
the .cpp file. However, this can cause problems, e.g. when other functions are in the .cpp file. It will also likely increase the compile time.
A clean way is to move your template functions into its own .cpp file, and include that in the header or use the export
keyword and compile it separately.
More information on why you should try and put template function definitions in its header file (and ignore export altogether).
The best practice with template functions is to define them in header files. They are created at compile time so compiler has to have definition around to do so.
When export
for templates would be more supported this wouldn't be the case though but right now it still hardly can be used.