Шаблон C++, ошибка компоновки

У меня проблема с вызовом класса шаблона, который у меня есть. Я объявил новый тип имени Array, который является шаблоном;

В файле.hpp:

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

В файле.cpp:

template <typename T>
Array<T>::Array()
{
//Do something
}

В основном:

Array<int> arr;

Я получаю сообщение об ошибке: неразрешенный внешний символ в ctor.

Любая идея?

6 ответов

Решение

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

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

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

Проблема, с которой вы столкнулись, заключается в том, что вы скрыли определение конструктора в файле.cpp. Это определение относится ко всем типам T, в том числе T как int что вы используете, но на самом деле не дает никаких определений, потому что это все еще только декларация.
Компоновщик не может найти символ Array<int>::Array(),

Теперь вы можете добавить такую ​​строку:

Array<int> arr1;

до конца вашего файла Array.cpp, и это заставляет компилятор создавать правильное определение, которое ищет компоновщик. Однако это дает только одно определение Array<int> и нет другого.

Это решение будет работать, пока вам не понадобится Array другого параметра шаблона, скажем, doubleв этот момент вам нужно будет добавить:

Array<double> arr2;

в конец вашего файла Array.cpp - теперь вы можете увидеть, как это неустойчиво!

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

Как упоминалось выше, в шаблонах в C++ процесс новых методов выполняется компилятором во время компиляции, проблема в том, что ему нужно знать все определения thm за это время, поэтому все объявления классов / функций должны быть ar h или hpp файлы.

Другой ответ: скомпилируйте только ваш файл.cpp (не основной) и проверьте размер объектного файла, затем создайте пустой файл.cpp, а затем скомпилируйте этот empty.cpp. наконец, сравните размер обоих объектных файлов. Вы увидите, что они имеют одинаковый размер, что означает, что ваш файл.cpp ничего не значит для компилятора, поэтому компоновщик не может ничего найти.

Другие вопросы по тегам