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.
