I have a header file which contains the class with only function declarations. I then define the function in a separate cpp file. However, I get linker errors when I do this. If I define the function in the header file (but outside the class) I don't get linker errors. Why would it matter whether the function was defined inside the header or cpp file?

The function insertVertex is giving me problems.

GraphEdgeList.h
Code:
#ifndef GRAPHEDGELIST_H
#define GRAPHEDGELIST_H

#include <vector>
#include <list>

template <typename Object>
class Vertex {
private:
    template <typename> friend class GraphEdgeList;
    Object o;
    int undirectedDegree;
    int inDegree;
    int outDegree;
public:
    Vertex(const Object& oo = Object()) : o(oo), undirectedDegree(0),
        inDegree(0), outDegree(0)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

template <typename Object>
class Edge {
private:
    template <typename> friend class GraphEdgeList;
    typedef Vertex<Object> Vertex;
    Object o;
    Vertex* origin;
    Vertex* destination;
    bool isDirected;
public:
    Edge(const Object& oo = Object(), Vertex* org = NULL, Vertex* dst = NULL,
        bool directed = false)
        : o(oo), origin(org), destination(dst), isDirected(directed)
    {
    }
    const Object& element() const {
        return o;
    }
    void element(const Object& oo) {
        o = oo;
    }
};

/*
 * A graph represented by an edge list
 */
template <typename Object>
class GraphEdgeList {
    typedef Vertex<Object> Vertex;
    typedef Edge<Object> Edge;
    std::list<Vertex> V;
    std::list<Edge> E;
public:
    Vertex& insertVertex(const Object& o);
};

#ifdef DEFINEINHEADER

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex(o));
    return V.back();
}

#endif

#endif
GraphEdgeList.cpp
Code:
#include "GraphEdgeList.h"

#ifdef DEFINEINCPP

template <class Object>
typename GraphEdgeList<Object>::Vertex&
GraphEdgeList<Object>::insertVertex(const Object& o) {
    typedef typename GraphEdgeList<Object>::Vertex Vertex;
    V.push_back(Vertex(o));
    return V.back();
}

#endif
main.cpp
Code:
#define DEFINEINCPP // this gives linker errors
//#define DEFINEINHEADER // this works
#include "GraphEdgeList.h"
#include <iostream>
#include <utility>
#include <string>

int main() {
    GraphEdgeList<std::string> g;
    g.insertVertex("SFO");
}