Шаблоны C++, неопределенная ссылка
у меня есть функция, объявленная следующим образом:
template <typename T>
T read();
и определяется следующим образом:
template <typename T>
T packetreader::read() {
offset += sizeof(T);
return *(T*)(buf+offset-sizeof(T));
}
однако, когда я пытаюсь использовать его в моей функции main ():
packetreader reader;
reader.read<int>();
Я получаю следующую ошибку от G++:
g++ -o main main.o packet.o
main.o: In function `main':
main.cpp:(.text+0xcc): undefined reference to `int packetreader::read<int>()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
может ли кто-нибудь указать мне в правильном направлении?
4 ответов
вам нужно использовать export
ключевое слово. Однако я не думаю, что G++ имеет надлежащую поддержку, поэтому вам нужно включить определение функции шаблона в заголовок, чтобы единица перевода могла его использовать. Это потому что <int>
"версия" шаблона не была создана, только <typename T>
'версия.'
самый простой способ -#include
the .файл cpp. Однако, это может вызвать проблемы, например, когда другие функции в рамках .файл cpp. Это также, вероятно, увеличит компиляцию время.
чистый способ-переместить функции шаблона в свои собственные.cpp-файл и включите его в заголовок или использовать export
ключевое слово и скомпилировать его отдельно.
проблема в том, что шаблон функции не является функцией. Это шаблон для создания функций по мере необходимости.
таким образом, для работы шаблона компилятору интуитивно нужны две части информации: сам шаблон и тип, который должен быть заменен в него.
Это не похоже на вызов функции, который компилятор может генерировать, как только он знает, что функция существует. Ему не нужно знать, что делает функция, просто она выглядит как void Frobnicate(int, float)
, или как там его подпись.
когда вы объявляете шаблон функции без его определения, вы только говорите компилятору, что такой шаблон существует, но не то, как он выглядит. Этого недостаточно для компилятора, чтобы иметь возможность создавать его экземпляр, он также должен иметь возможность видеть полное определение. Обычным решением является поместить весь шаблон в заголовок, который может быть включен там, где это необходимо.
лучшая практика с функциями шаблона-определить их в файлах заголовков. Они создаются во время компиляции, поэтому компилятор должен иметь определение для этого.
, когда export
для шаблонов было бы более поддержано это не было бы так, но прямо сейчас его все еще вряд ли можно использовать.
является ли их шаблон поддержки компилятора отдельной компиляцией?
Как я знаю, общей практикой является объявление и реализация функций шаблона в заголовочном файле