I have a problem with compiling and linking the main.cxx and Vec.cxx files, which are shown below.
To compile, I am using g++ with the following command:g++ -std=c++11 -c main.cxx Vec.cxx
. To link, simply g++ main.o Vec.o
. But doing this I get undefined reference errors to the create and uncreate functions, which are used by the constructors and the destructor.
Vec.cxx:
// Vec.cxx
// Source file for Vec template class header.
#include "Vec.h"
#include <memory>
template <class T> Vec<T>& Vec<T>::operator=(const Vec& rhs){
if(&rhs != this){
// free array in the left hand side
uncreate();
create(rhs.begin(),rhs.end());
}
return *this;
}
template <class T> void Vec<T>::create(){
data = avail = limit = 0;
return;
}
template <class T> void Vec<T>::create(size_type n, const T& val){
data = alloc.allocate(n);
limit = avail = data + n;
std::uninitialized_fill(data,limit,val);
return;
}
template <class T> void Vec<T>::create(const_iterator b,const_iterator e){
data = alloc.allocate(e-b);
limit = avail = std::uninitialized_copy(b,e,data);
return;
}
template <class T> void Vec<T>::uncreate(){
if (data) {
// Destroy (in reverse order) the constructed elements;
iterator it = avail;
while(it != data){
alloc.destroy(--it);
}
// Return all the space that was allocated
alloc.deallocate(data, limit-data);
}
data = limit = avail = 0;
return;
}
template <class T> void Vec<T>::grow(){
size_type new_size = std::max(2* (limit-data), std::ptrdiff_t(1));
iterator new_data = alloc.allocate(new_size);
iterator new_avail = uninitialized_copy(data,avail,new_data);
uncreate();
data = new_data;
avail = new_avail;
limit = data + new_size;
return;
}
template <class T> void Vec<T>::unchecked_append(const T& val){
alloc.construct(avail++,val);
return;
}
Vec.h:
#ifndef VEC_H
#define VEC_H
#include <memory>
template<class T> class Vec{
public:
// define names
using iterator = T*;
using const_iterator = const T*;
using size_type = size_t;
using value_type = T;
// Size and index operators
size_type size() const { return avail - data; }
T& operator[] (size_type i) { return data[i]; }
const T& operator[] (size_type i) const { return data[i]; }
// Constructors
Vec() { create(); }
explicit Vec(size_type n, const T& val = T()) { create(n, val); }
Vec(const Vec& v) { create(v.begin(),v.end()); }
// Destructor
~Vec() { uncreate(); }
// Assignment operator
Vec& operator=(const Vec&);
// push_back function
void push_back(const T& val){
if(avail == limit){
grow();
}
unchecked_append(val);
return;
}
// Iterators
iterator begin() { return data; }
const_iterator cbegin() const { return data; }
const_iterator begin() const { return data; }
iterator end() { return limit; }
const_iterator end() const { return limit; }
const_iterator cend() const { return limit; }
private:
iterator data; // First element in Vec
iterator avail; // One past the last allocated memory element
iterator limit; // One past the last element in Vec
std::allocator<T> alloc;
void create();
void create(size_type, const T&);
void create(const_iterator,const_iterator);
void uncreate();
void grow();
void unchecked_append(const T&);
};
#endif
main.cxx:
#include "Vec.h"
int main(int argc, char **argv){
Vec<int> v(10,2);
return 0;
}
Edit: Thankyou for marking as duplicate, the link resolved my question. I moved the functions into the header file and everything works now.