неопределенная ссылка с реализацией члена шаблонного класса - PullRequest
0 голосов
/ 03 августа 2010

Это совершенно загадочно для меня. Я использую g ++ в Ubuntu, и это часть моего кода (с изменением имен классов, но больше ничего, потому что я все еще использую заглушки везде):

Bob.hpp

template <class A>
class Bob : public Jack<Chris, A>
{
    public: 

        Bob(int x1, int x2, float x3 = 1.0, float x4 = 2.0, float x5 = 3.0) throw(Exception);
        virtual ~Bob();
};

Я реализовал в другом файле, как это:

Bob.cpp

template <class A>
Bob<A>::Bob(int x1, int x2, float x3, float x4, float x5) throw(Exception)
{

}

template <class A>
Bob<A>::~Bob()
{

}

и я использовал это так:

main.cpp

int main()
{
    Bob<Alice> instance(1, 2);
}

Компиляция с:

g++ -c Bob.cpp -o Bob.o
g++ -c main.cpp -o main.o
g++ -L"libs" -llib main.o Bob.o prog

дает мне main.o: В функции main': main.cpp:(.text+0x1fd): undefined reference to Bob :: Bob (int, int, float, float, float) ' collect2: ld вернул 1 статус выхода

Я полностью в тупике. Изменение порядка на этапе связывания g ++ не имеет значения. Компиляция объектных файлов не создает проблем. И почему неопределенная ссылка, когда я реализовал конструктор? Если кто-то может пролить свет на это, это будет высоко ценится.

Ответы [ 4 ]

1 голос
/ 03 августа 2010

Вам нужно переместить код из Bob.cpp в Bob.hpp.Когда компилятор видит определения Bob::Bob и Bob::~Bob в Bob.cpp, он не знает, какие типы Боба будут созданы (например, Bob<int> против Bob<SomeClass>, а код для них - нет).В качестве альтернативы, вы все равно можете поместить код в файл Bob.cpp, но вам нужно объявить, какие типы Боба будут созданы, например: Внутри Bob.cpp:

template
class Bob<Alice>;
1 голос
/ 03 августа 2010

Все объявления и определения функций-членов шаблона класса должны находиться в одном заголовочном файле.

При компиляции Bob.cpp компилятору доступны как объявления, так и определения.На этом этапе компилятору не нужно генерировать какие-либо определения для шаблонных классов, так как нет никаких экземпляров.Когда компилятор компилирует main.cpp, создается экземпляр: шаблон класса Bob<Alice>.На данный момент у компилятора есть объявления, но нет определений!

0 голосов
/ 03 августа 2010

Где, по вашему мнению, должен быть определен конструктор Bob<Alice>? Он не был определен в Bob.cpp, потому что в Bob.cpp не было упоминания Bob<Alice>. Был шаблон , который можно было использовать для определения Bob<Alice>, когда Bob.cpp был скомпилирован в Bob.o, но это не так.

Поместите определение шаблона в Bob.hpp или Bob<Alice> в Bob.cpp.

0 голосов
/ 03 августа 2010

В дополнение к проблемам, поднятым другими, библиотеки должны стоять последними в командной строке GCC. Вместо:

g++ -L"libs" -llib main.o Bob.o prog

Вы хотите:

g++ -L"libs"  main.o Bob.o prog -llib
...