This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Undefined reference error for template method [duplicate]
(3 answers)
Closed 9 years ago.
I cannot link object files. Compilation works fine, but the linker gives me these error messages:
testArguments.o: In function Z6__mainiPPc':
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:5:
undefined reference toArguments::Arguments()'
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:6:
undefined reference to Arguments<int>::insertItem(int)'
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:8:
undefined reference to_Unwind_Resume' testArguments.o: In function
ZNSt10_List_baseIiSaIiEED2Ev':
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_list.h:378:
undefined reference to_Unwind_Resume' testArguments.o: In function
ZN9__gnu_cxx13new_allocatorISt10_List_nodeIiEE10deallocateEPS2_j':
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/ext/new_allocator.h:110:
undefined reference tooperator delete(void*)'
testArguments.o:testArguments.cpp:(.eh_frame+0x13): undefined
reference to __gxx_personality_v0'
testArguments.o:testArguments.cpp:(.eh_frame$_ZNSt10_List_baseIiSaIiEED2Ev+0x13):
undefined reference to__gxx_personality_v0' Makefile:7: recipe for
target 'tests' failed
But these functions are defined in the cpp file (Argument::Arguments() Arguments::insertItem(int)
Here is my header file:
#ifndef ARGUMENTS_H
#define ARGUMENTS_H
#include <list>
using std::list;
template<class T>
class Arguments{
public:
Arguments(list<T> args);>
Arguments()>;
void insert>Item(T item);
list<T> getValues();
private:
list<T> values;
};
#endif
Here the cpp file:
#include "include/Arguments.h"
#include <list>
using std::list;
template<class T> Arguments<T>::Arguments(list<T> args) {
values = args;
}
template<class T> Arguments<T>::Arguments() {
}
template<class T> void Arguments<T>::insertItem(T argument){
values.push_back(argument);
}
template<class T> list<T> Arguments<T>::getValues() {
return this.values;
}
Related
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 3 years ago.
I tried to make an Array template class but when I try to build the compiler fails to link the constructor and the method and I get :
undefined reference to `Array::Array()
undefined reference to `Array::getSize()
Here is the header file:
#pragma once
template<typename type, int length>
struct Array{
public:
Array();
int getSize();
private:
type data[length];
int m_length;
};
The Array.cpp file:
#include "Array.h"
template<typename t, int l>
Array<t, l>::Array()
{
m_length = l;
}
template<typename type, int length>
Array<type, length>::getSize()
{
return m_length;
}
And the main function:
#define LOG(x) cout<<x<<endl
int main()
{
Array<int, 10> array;
LOG(array.getSize());
}
If someone has any idea about why I am getting this, I would really appreciate.
You need to either put your implementation into the header files, or define the usage (instantiation of the template arguments) in the source file
So I have made a little bit of C++ templates before: some quite basic examples of the curiously recurring template pattern for classes of mathematical numbers. This time I tried using the same pattern to create a list or "network" for objects of a class which they could add themselves to and look around for other objects. I thought I could use a static std::list to do this. So my attempt goes like this:
template<class C> class HasNetwork{
public:
HasNetwork(){}
static list<C*> m;
};
template<class C> list<C*> HasNetwork<C>::m = list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
public:
IHaveNetwork(){ m.push_back(this); }
};
int main(){
IHaveNetwork lHF, lHF2;
//for(list<IHaveNetwork*>::iterator it = lHF.m->begin(); ; it++);
return 0;
}
It seems to compile, but I get nasty link errors ( even with the for loop iterator commented out ). Maybe I need to do some cast or maybe "this" is not defined until after the constructor finishes?
Here is the link error:
/tmp/templatest-912860.o: In function `__clang_call_terminate':
templatest.cpp:
(.text.__clang_call_terminate[__clang_call_terminate]+0x9): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*>
>::deallocate(std::_List_node<IHaveNetwork*>*, unsigned long)':
templatest.cpp:
(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m]+0x1c): undefined reference to `operator delete(void*)'
/tmp/templatest-912860.o: In function `std::list<IHaveNetwork*, std::allocator<IHaveNetwork*>
>::_M_insert(std::_List_iterator<IHaveNetwork*>, IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_]+0x31): undefined reference to
`std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
/tmp/templatest-912860.o: In function `std::list >::_M_create_node(IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xa0): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xbb): undefined reference to `__cxa_rethrow'
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xce): undefined reference to `__cxa_end_catch'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*> >::allocate(unsigned long, void const*)':
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x33): undefined reference to `std::__throw_bad_alloc()'
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x40): undefined reference to `operator new(unsigned long)'
/tmp/templatest-912860.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
I cannot reproduce.
Here is a slightly modified version of you code that compiles links and runs without even a warning (I only had to fix some indirection level errors):
#include <iostream>
#include <list>
#include <string>
template<class C> class HasNetwork{
public:
HasNetwork(){}
static std::list<C*> m;
};
template<class C> std::list<C*> HasNetwork<C>::m = std::list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
std::string name;
public:
IHaveNetwork(const std::string &name): name(name) { m.push_back(this); }
std::string getName() const {
return name;
}
};
int main(){
IHaveNetwork lHF("foo"), lHF2("bar");
for(std::list<IHaveNetwork*>::iterator it = lHF.m.begin(); it != lHF.m.end(); it++) {
std::cout << (*it)->getName() << std::endl;
}
return 0;
}
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
I have this class in my .hpp file
template<class T = int>
class Matrix
{
public:
Matrix();
}
and I have this Matrix.cpp file
#include "Matrix.hpp"
template<class T>
Matrix<T>::Matrix()
{
vector<T> vecN(1, 0);
_matrix.resize(1, vecN);
_rows = 1;
_cols = 1;
}
but it won't work, when adding a main
#include "Matrix.hpp"
int main(int argc, char** argv)
{
Matrix<int> test();
return 0;
}
i get a very weird error saying
main.cpp:19: undefined reference to Matrix<int>::Matrix(unsigned int, unsigned int)'
main.cpp:19:(.text+0x2d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol Matrix<int>::Matrix(unsigned int, unsigned int)
Template code must be in the header, unless it is for specialisations.
This is because the template is used to generate the actual class when you use it.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
I'm trying to make a simple bounds checked array in C++. I have declared a class in a header file, and defined the class in a separate source file. The compile step runs fine, but when I try to link the objects, I get the following error:
$ g++.exe -o a.exe src\main.o src\array.o
src\main.o: In function `main':
../src/main.cpp:7: undefined reference to `Array<int>::Array(int)'
../src/main.cpp:9: undefined reference to `Array<int>::operator[](int)'
../src/main.cpp:10: undefined reference t o `Array<int>::operator[](int)'
../src/main.cpp:11: undefined reference t o `Array<int>::operator[](int)'
../src/main.cpp:13: undefined reference t o `Array<int>::operator[](int)'
../src/main.cpp:7: undefined reference to `Array<int>::~Array()'
../src/main.cpp:7: undefined reference to `Array<int>::~Array()'
collect2.exe: error: ld returned 1 exit status
main.cpp
#include <iostream>
#include "array.hpp"
using namespace std;
int main() {
Array<int> x(10); // compiler error
x[0] = 1; // compiler error
x[1] = 2; // compiler error
x[2] = 3; // compiler error
cout << x[1] << endl; // compiler error
return 0;
}
array.hpp
#ifndef ARRAY_HPP_
#define ARRAY_HPP_
template <class T>
class Array{
private:
T* array;
int length_;
public:
Array(int);
~Array();
int Length();
int& operator[](int);
};
#endif /* ARRAY_HPP_ */
array.cpp
#include "array.hpp"
template <class T>
Array<T>::Array(int size) {
length_ = size;
array = new T[size];
}
template <class T>
Array<T>::~Array() {
delete[] array;
}
template <class T>
int Array<T>::Length() {
return length_;
}
template <class T>
int& Array<T>::operator[](const int index) {
if (index < 0 || index >= length_) {
throw 100;
}
return array[index];
}
Definitions of members of a template class shall be in the same header where the template class is defined itself.
Template classes must have all their code in the header file or they can only be used for types you explicitly instantiated in the cpp file.
This question already has answers here:
Why do I get "unresolved external symbol" errors when using templates? [duplicate]
(3 answers)
Closed 9 years ago.
I'm pretty new with templates, so please don't be harsh on me if my code is very wrong :)
This is the header file for a class Key that uses a template:
//Key.h
#ifndef KEY_H
#define KEY_H
#include "../Constants.h"
template<class KeyType>
class Key
{
public:
Key<KeyType>(KeyType initial);
KeyType increment();
private:
KeyType current;
};
#endif /* KEY_H */
This is the .cpp file of Key class:
//Key.cpp
#include "Key.h"
template<class KeyType> Key<KeyType>::Key(KeyType p_initial)
{
this->current = p_initial;
}
template<class KeyType> KeyType Key<KeyType>::increment()
{
this->current ++; //KeyType should implement this operator
}
So what's the problem? I try to create an instance of Key somewhere else in my code, like this:
Key songID (0); // ERROR: undefined reference to Key<int>::Key(int)
and then use
songID.increment(); // ERROR: undefined reference to Key<int>::increment()
Two points:
Remove <KeyType> from Key<KeyType>(KeyType initial); you don't need it.
And, move class implementation from .cpp file to .h file. Thie article is useful: Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?