In general, templates are implemented in the header files (as many answers in Stack Overflow point out) so the code template is available to the compiler when it needs it to create a new instance of the class/function. However, in my case, some of the methods in my template class can be used only for a certain type, so my class looks like:
Class header
#ifndef LEC_H
#define LEC_H
#include <iostream>
template <typename T>
class LEC
{
public:
LEC()
{
}
void func() const;
void func2() const
{
std::cout << "Func 2" << std::endl;
}
};
#endif // LEC_H
Class cpp
#include "lec.h"
template <typename T>
void LEC<T>::func() const
{
std::cout << "Func: " << typeid(T).name() << std::endl;
}
template class LEC<float>;
template class LEC<double>;
The last two lines of the cpp file allow me to use func()
because I explicitly instantiate this class template for these two types. When I use this class template in a program I can use any type as long as I do not call func()
:
#include "lec.h"
int main()
{
LEC<float> a;
LEC<double> b;
a.func2();
a.func();
b.func2();
b.func();
LEC<char> c;
c.func2();
return 0;
}
But, since the code is not available for the compiler to intsantiate func()
for a LEC
class with type char
, I cannot do c.func()
or I will get a compiler error:
undefined reference to `LEC::func() const'
This is a simplification of my real code. However, in my code, when I do LEC<char> c
to create an instance of the class I get the error, without calling any methods, only by constructing the class.
- Any idea on how to find out why this, apparently not used method, has to be linked anyways?
- Is there a way so the compiler (in my case I am using clang++: clang version 6.0.0-1ubuntu2) points out where is this method used within the code?
- Otherwise, can somebody explain why this (not having to link to a non-used class method) is working in the provided example and not in my code?
Edit The cmake looks like:
add_library(lec_lib SHARED lec.cpp lec.h)
add_executable(lec_main main.cpp)
target_link_libraries(lec_main lec_lib)
Hence, the compiled library is linked with the executable.
Edit 2
Please avoid suggesting answers such as Why templates can only be implemented in the header file since I already know that the template has to be available to the compiler when the class is instantiated for a new type. My question is different. Why can I instantiate a type for which not all the template implementations are available as long as I do not use the specific class methods for which the template implementation is not provided at instantiation time (in the example case func()
)
Edit 3
Regarding the suggestion that this is a duplicate of What is an undefined reference/unresolved external symbol error and how do I fix it?. Again my question is different. I am looking for answers on why in the example I can instantiate LEC<char>
when LEC<char>::func()
is not visible for the compiler when it compiles the main program. And inthe case that this cannot be done and L3C<char>::func()
is required to be linked, how to find why the method linkage is required while it is not being used (which is what happens in my real code).