2012-03-26 2 views
0

У меня есть следующие три файла в том же каталоге:Невозможно Ссылка на Си ++

citysim.cpp

#include "utils.h" 
using namespace std; 

int main() 
{ 
    City *c; 
    c = new City(); 
    Graph<City *> g; 
    g.addVertex(c); 
} 

utils.h

#include <iostream> 
#include <map> 
#include <vector> 
using namespace std; 

class City { 
    public: 
     City() {} 
    private: 
     string name; 
}; 

template <typename Tkey> 
class Graph { 
    public: 
     Graph() {} 
     void addVertex(Tkey); 
    private: 
     vector<Tkey> v; 
     vector< vector<int> > e; 
     map<Tkey, int> key_map; 
}; 

Utils. cpp

#include "utils.h" 

template <typename Tkey> 
void Graph<Tkey>::addVertex(Tkey vertex) 
{ 
    v.push_back(vertex); 
} 

И я действительно недоумевал, почему следующая последовательность компиляции выдает результат показали:

test> g++ -c citysim.cpp 
test> g++ -c utils.cpp 
test> g++ -o citysim citysim.o utils.o 
citysim.o: In function `main': 
citysim.cpp:(.text+0x4a): undefined reference to `Graph<City*>::addVertex(City*)' 
collect2: ld returned 1 exit status 

Любые идеи или идеи приветствуются!

+0

Возможный дубликат [Почему я получаю ошибку Linker с указателем функции шаблона?] (Http://stackoverflow.com/questions/4763216/why-am-i-getting-a-linker-error-with-template -function-pointer) – 6502

+0

Пожалуйста, не используйте 'using namespace std;' в файле заголовка. – quamrana

+0

Хорошо, почему бы и нет? Разве мне не нужно было бы префикс std :: string, vector, map и т. Д.? Спасибо, я бы очень хотел узнать. – user434462

ответ

1

Определите все свой шаблонный класс в файле заголовка, а не в файле cpp. Вместо того, чтобы ваш utils.cpp есть все, как это в файле заголовок:

template <typename Tkey> 
class Graph { 
public: 
    Graph() {} 
    void addVertex(Tkey vertex) 
    { 
     v.push_back(vertex); 
    } 
private: 
    vector<Tkey> v; 
    vector< vector<int> > e; 
    map<Tkey, int> key_map; 
}; 

Here является связанным с чтением в Справке ...

EDIT: (Но вы можете определить его в дальнейшем как вы сделали это и в своем cpp в файле заголовка ...)

+0

А, поэтому шаблонная декларация класса и определения ее членов должны появляться в тот же файл. Отличная информация, спасибо! (Пробовал это, и это сработало.) – user434462

+0

На самом деле они не должны появляться в одном файле, но определение должно появиться хотя бы в одном файле, где создается экземпляр шаблона. Таким образом, вы можете скрыть определение в файле .cpp, если вы также создаете его там для всех типов, которые используют его в вашей системе. –

0

Функции шаблона должны быть полностью написаны на заголовке, их определения не могут выполняться в файле cpp.

+0

Спасибо! Урок выучен. – user434462

+0

Неправда, см. Мой комментарий на ответ @ niktehpui. –

+0

Да, знайте это. Но вместо объяснения этого лучше сказать правило gereal, а не объяснять, что шаблоны оцениваются во время компиляции и фактически производят одну другую функцию для каждого используемого типа. – Castilho

Смежные вопросы