Почему при использовании шаблонов я получаю ошибки «неразрешенных внешних символов»?

Когда я пишу код C ++ для classа с использованием шаблонов и разделяю код между исходным (CPP) файлом и файлом заголовка (H), я получаю множество ошибок «неразрешенных внешних символов», когда речь идет о соединении окончательного исполняемого файла, несмотря на то, что объектный файл правильно построен и включен в ссылку. Что здесь происходит, и как я могу это исправить?

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

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

    Решения, доступные для этого:

    1. включить полное определение функции-члена в файл заголовка шаблона и не иметь исходный файл для шаблона,
    2. определить все функции-члены в исходном файле шаблона как «inline» или
    3. определите функции-члены в источнике шаблона с ключевым словом «export». К сожалению, это не поддерживается многими компиляторами. (Обновление: это было удалено из стандарта с C ++ 11. )

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

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

    Для каждого файла, который содержит файл .h, вы должны вставлять обе строки:

     #include "MyfileWithTemplatesDeclaration.h" #include "MyfileWithTemplatesDefinition.cpp" 

    образец

     #include "list.h" #include "list.cpp" //<---for to fix bug link err 2019 int main(int argc, _TCHAR* argv[]) { list my_list; my_list.add_end(3); . . } 

    Кроме того, вы не забудьте разместить свой class объявлений среди сантинельных констант

     #ifndef LIST_H #define LIST_H #include  . . template  class list { private: int m_size, m_count_nodes; T m_line; node *m_head; public: list(void); ~list(void); void add_end(T); void print(); }; #endif 
    Interesting Posts

    Автоматически переименовывать файл, если он уже существует в Windows

    Java-реализация преобразования JSON в XML

    Нужно ли обертывать кавычки именами шрифтов в CSS?

    Как вернуть накопленные результаты нескольких (параллельных) асинхронных вызовов функций в цикле?

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

    угловой ng-bind-html и директива внутри него

    Цвет фона альтернативной сетки в excel при изменении значения одного столбца?

    Попытка открыть книгу в отдельном экземпляре

    Как я могу частично очистить прокрутку терминала?

    Как настроить проводное 1 к 1 сетевое соединение между двумя компьютерами?

    Загрузка изображения ASP.NET с изменением размера

    Как я могу использовать тип ввода электронной почты HTML5 с серверной .NET.

    Открыть html-страницу в браузере по умолчанию с помощью VBA?

    Печать с помощью sed или awk строки, соответствующей шаблону соответствия

    Проблемы с маршрутизатором MBR624GU Netgear

    Давайте будем гением компьютера.