Unresolved externals with an explicit template. What is ad syntax?

Here is some simplified code to demonstrate the problem I have.

I have a template function for which I only want to compile certain fixed instances.

Function declarations:

// *** template.h *** int square (int x); double square (double x); 

Definitions:

 // *** template.cpp *** #include "template.h" // (template definition unusually in a code rather than header file) template <typename T> T square (T x) { return x*x; } // explicit instantiations template int square (int x); template float square (float x); 

And an example of use:

 // *** main.cpp *** #include <iostream> using namespace std; #include "template.h" int main (void) { cout << square(2) << endl; cout << square(2.5) << endl; } 

Attempting to compile this results in link errors, approximately:

main.obj: unresolved external symbol "int square (int)" referenced by main

I understand what the problem is: the function signatures of my explicit template instances do not match those contained in the header file.

What is the syntax for declaring explicit template instances, please? I do not want to forward the template definition declaration or move the template definition to the header file.

For what it's worth, I have a workaround that should use wrapper functions by adding the following to the above files:

 // *** template.cpp *** // ... // wrap them [optionally also inline the templates] int square (int x) { return square<> (x); } double square (double x) { return square<> (x); } 

This compiles and works as expected. However, this seems like a hack to me. There must be something more elegant than what is available in the C ++ syntax and the template.

Any help or tips would be greatly appreciated.

+4
source share
2 answers

You need to declare a function template in your header:

 template <typename T> T square(T x); 

As you now do this, you declare two non-standard functions in the header that are never defined.

+5
source

There is no other way if you want to hide the template from the header file. You must have wrapper functions because int square (int x); does not have the same name as template int square (int x); and C ++ does not offer you a way to change this.

As an example, you can check how name mixing differs in Visual Studio .

+1
source

Source: https://habr.com/ru/post/1304900/


All Articles