Определение методов класса с параметрами шаблона - PullRequest
0 голосов
/ 14 августа 2011

Файл main2.cpp:

#include "poly2.h"

int main(){
 Poly<int> cze;
 return 0;
}

Файл poly2.h:

template <class T>
class Poly {
public:
 Poly();
};

Файл poly2.cpp:

#include "poly2.h"

template<class T>
Poly<T>::Poly() {
}

Ошибка при компиляции:

src$ g++ poly2.cpp main2.cpp -o poly
/tmp/ccXvKH3H.o: In function `main':
main2.cpp:(.text+0x11): undefined reference to `Poly<int>::Poly()'
collect2: ld returned 1 exit status

Я пытаюсь скомпилировать приведенный выше код, но во время компиляции возникают ошибки.Что нужно исправить, чтобы компилировать конструктор с параметром шаблона?

Ответы [ 4 ]

4 голосов
/ 14 августа 2011

Полный код шаблона должен отображаться в одном файле.Вы не можете разделить интерфейс и реализацию между несколькими файлами, как это было бы с обычным классом.Чтобы обойти это, многие люди пишут определение класса в заголовке, а реализацию - в другом файле и включают реализацию в конец файла заголовка.Например:

Blah.h:

#ifndef BLAH_H
#define BLAH_H

template<typename T>
class Blah {
    void something();
};

#include "Blah.template"

#endif

Blah.template:

template<typename T>
Blah<T>::something() { }

И препроцессор выполнит эквивалент копирования-вставки содержимогоBlah.template в заголовок Blah.h, и все будет в одном файле к тому времени, когда компилятор увидит его, и все будут счастливы.

1 голос
/ 14 августа 2011

Вечный вопрос о том, как мне определить мои шаблоны классов.Шаблон на самом деле не код, это шаблон, который вы используете для определения кода позже.Итак, есть два возможных решения: если вы знаете, что вы собираетесь использовать только определенные типы Poly, вы можете определить их в файле .cpp.

#include "poly2.h"
Poly<int>;

template<class T>
Poly<T>::Poly() {
}

Или вы можетепоместите все определения и объявления шаблона в ваш заголовочный файл.Мне нравится создавать отдельный файл .hpp и помещать туда определения.Итак, я бы сделал это:

poly2.h

template <class T>
class Poly {
public:
 Poly();
};
#include "poly2-impl.hpp"

poly2-impl.hpp

template<class T>
Poly<T>::Poly() {
}

И в шаблонах важно то, что вы можете включить заголовокфайл в нескольких файлах перевода без ранее определенных ошибок.

Дополнительную информацию см. здесь: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

1 голос
/ 14 августа 2011

Если вы используете шаблоны в C ++, все реализации функций, которые используют шаблоны, должны находиться внутри вашего заголовочного файла.Или ваш компилятор не может найти правильную (или любую) версию для типа.

Подробнее см. this .

0 голосов
/ 14 августа 2011

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

К сожалению, не все так просто, когда шаблоны входят в микс. Поскольку шаблоны должны быть созданы при использовании, их определения должны быть видны при использовании. main2.cpp не может увидеть определение Poly<int>::Poly(), поэтому эта функция не реализована. Таким образом, он отсутствует в объектном файле и не может быть связан.

Вам следует писать шаблоны функций в заголовочных файлах, чтобы они были доступны во всех единицах перевода, в которых вы их используете. Это не идеально, но без export (или без явного создания экземпляра) с этим ничего не поделаешь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...