instantiating a class template and call its methods [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
When I include MyClass.h and do:
MyClass<int, int> ccc = MyClass<int, int>();
ccc.myMethod1(3, 4);
I get a lot of errors telling undefined reference to constructor and methods ... However when I include MyClass.cpp (which is not a proper why to code) there is no error ! How to fix that ?
I'm compiling under Code::Blocks using g++

The reason is that template classes are not compiled, only instantiated templates will be compiled.
Rule of thumb: don't place template implementations in a cpp file but either directly in the header or another file included by the header (if you want to part implementation from the interface).
E.g:
myclass.h
template<typename A>
class MyClass
{
...
};
#include "myclass.inc"
myclass.inc
//implementation goes here:
....

Related

Why multiple definitions of a template does not generate a link error? [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 1 year ago.
Assume these two cc files:
0.cc
#include <iostream>
template <class T>
T test(){
return 5;
}
int main(){
return test<int>();
}
1.cc
template <class T>
T test(){
return 5;
}
We compile them with g++ 0.cc 1.cc.
This compiles and runs successfully but if above functions were not templates then we would get a duplicate symbol error during compilation and linking phase.
Why using templates does not generate a link error?
Template is not instantiated until it is called in the code. Think of it as a local function to the compiled object.
Therefore, template as such is not exported and is not subject to linking of any kind, as it can't be referenced from another object. Should you be calling template defined in another header, it would still be instantiated in the local object.

Undefined reference to not used class template method [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
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).

Static variable in h-file C++ template library. Is it OK? [duplicate]

This question already has answers here:
How to have static data members in a header-only library?
(3 answers)
Closed 6 years ago.
I am developing lightweight parser as C++ h-file template library.
Gramma is described in specific BNF-like notation using overloaded operators on some classes which should be enumerated somehow. I need just one global variable as some counter performing it.
I do not want to use extern int var; in h-file and int var; in cpp-file because all my stuff in single header file and now the user just needs to include it.
I can declare static int var; in header file but copy of this variable appears in all object files where my header file is included.
Is it OK for template library?
Any suggestions?
As already mentioned you can use singleton pattern.
This version doesn't require definition of static member in template cpp file.
template <typename T> class Tmpl
{
public:
static Tmpl<T>& GlobalInstance()
{
static Tmpl<T> m_Singleton;
return m_Singleton;
};
};

C++ Connecting two .cpp files [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 years ago.
I have a problem connecting two .cpp files in C++. Here are my files
Header.h
//Header.h
template <class T> class asd{
asd();
check();
print();
}
file1.cpp
//file1.cpp
//defines all methods in class asd
#include "Header.h"
template<class T> asd<T>:: asd(T a, T b){//codes}
template<class T> T asd<T>:: check(T a){//codes}
template<class T> void asd<T>::print(){//codes}
file2.cpp
//file2.cpp
//main method
#include "Header.h"
int main(){//codes}
The thing I do not understand is that the code runs fine when I put main() inside file1.cpp, but it wont compile when I separate them into two files. Can someone please give pointers?
Edit:
For those with the same problem, solution can be found here:
http://www.cplusplus.com/forum/articles/14272/
Member functions of a class template should appear in the header file. Just move the function definitions from file1.cpp to Header.h.
Imagine you are the compiler. When compiling main, if you attempt to instantiate asd in any way, the compiler needs to be able to see the function definitions to generate the appropriate code. For example, if in main you do asd<int> my_asd;, the compiler needs to instantiate asd with T replaced with int. It can't do that for the functions if it can't see the function definitions.

separating constructor implementation with template from header file [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why should the implementation and the declaration of a template class be in the same header file?
My header file has
template <typename T>
class AA : public BB<T>
{
public:
AA()
{ ... }
this is working fine. But I need to separate the constructor implementation from header file.
So in cpp, I have
template <typename T>
AA<T>::AA()
{ ... }
When I compile this, it compiled but I get unresolved external symbol error. What am I missing here?
You can explicitly instantiate templates in your implementation file using :
template class AA<int>;
this will generate a definition from a template, but it is of use only if you know what types your class clients will use
If you put a template implementation into a .cpp file you need to make sure that it gets instantiated: the compiler won't do it automatically for you. Roughly the same question was answered about a day ago: do template always have to be in the header?