Template Static library with template creation

I am working on a static library, and the library has several class templates and function templates. I understand that for using templates inside a static library everything must be in the header file (declaration / definition). However, in this particular case, since I know the types of specialization, I thought I could use forward declaring the specialization.

This trick works great with class templates (and its functions), and I can use the entire library function from the application code. However, as soon as I enter the free function template inside the library, and I try to use the free template function from my application code, it gives me a linker error:

error LNK2019: unresolved external symbol "class TemplatedStaticLib __cdecl Registration assistance (int)" (?? $ HelpingRegistration @H @@ YA? AV? $ TemplatedStaticLib @H @@ H @Z) link in function _main 1> C: \ SRC \ CPP \ VS2008 \ StaticLibExample \ MathFuncsLib \ Debug \ TemplatedStaticLibApp.exe: fatal error LNK1120: 1 unsolved external "I am using VS2008, here is the code

// Static library header file (.h)

#ifndef _TEMPLATED_STATIC_LIB_ #define _TEMPLATED_STATIC_LIB_ #include <iostream> template<typename T> class TemplatedStaticLib { public: TemplatedStaticLib(){}; ~TemplatedStaticLib(){}; void print(T t); }; template<typename T> TemplatedStaticLib<T> HelpingRegistration(T); #endif 

// static library class file (.cpp)

 #include "TemplatedStaticLib.h" //Specialization template class TemplatedStaticLib<double>; template class TemplatedStaticLib<int>; template class TemplatedStaticLib<std::string>; template<typename T> void TemplatedStaticLib<T>::print(T t) { std::cout << "Templated Print " << typeid(t).name() << std::endl; } void HelpingRegistration(void) { } //Specialization of free function template<> TemplatedStaticLib<int> HelpingRegistration<int>(int); template<> TemplatedStaticLib<double> HelpingRegistration<double>(double); template<> TemplatedStaticLib<std::string> HelpingRegistration<std::string>(std::string); template<typename T> TemplatedStaticLib<T> HelpingRegistration(T t) { std::cout << "Function Templated Print " << typeid(t).name() << std::endl; return t; } 

// application code

 #include "TemplatedStaticLib.h" int main(int argc, char* argv[]) { int anInt = 99; TemplatedStaticLib<int> test; test.print(anInt);//works double aDouble = 3.9; TemplatedStaticLib<double> double_test; double_test.print(aDouble); //works std::string aString = "James"; TemplatedStaticLib<std::string> string_test; string_test.print(aString);//works //The following lines gives linker error HelpingRegistration(anInt); HelpingRegistration(aDouble); HelpingRegistration(aString); return 0; } 

I am not sure why this is different, and how I can fix it. Any help is appreciated.

+7
source share
1 answer

Remember, these are not forward declarations, but rather explicit instances of your class templates. This is what allows you to put the definition in .cpp files and not get an unresolved linker link error if you use only those template instances in other translation units.

On the other hand, they:

 template<> TemplatedStaticLib<int> HelpingRegistration<int>(int); template<> TemplatedStaticLib<double> HelpingRegistration<double>(double); template<> TemplatedStaticLib<std::string> HelpingRegistration<std::string>(std::string); 

These are declarations of explicit specializations of function templates. Most likely, you plan to use explicit instances . The syntax for this is as follows:

 template TemplatedStaticLib<int> HelpingRegistration<>(int); template TemplatedStaticLib<double> HelpingRegistration<>(double); template TemplatedStaticLib<std::string> HelpingRegistration<>(std::string); 

Once you fix this, you will see that the compiler will actually create an instance of your HelpingRegistration<>() function template, and at the same time it will also throw an error, because you are trying to convert int (a double or string respectively) to an object of type TemplatedStaticLib<int> (respectively TemplatedStaticLib<double> or TemplatedStaticLib<string> ), for which no conversion is provided (or at least not shown in the code you sent):

 template<typename T> TemplatedStaticLib<T> HelpingRegistration(T t) { std::cout << "Function Templated Print " << typeid(t).name() << std::endl; return t; // CANNOT BE CONVERTED! } 

Fixing this error (for example, when executing return TemplateStaticLib<T>(); ) will compile and link the program.

+8
source

All Articles