Как правило, шаблоны реализуются в файлах заголовков (как указано во многих ответах в Stack Overflow), поэтому шаблон кода доступен компилятору, когда он нужен для создания нового экземпляра класса / функции. Однако в моем случае некоторые методы в моем классе-шаблоне можно использовать только для определенного типа, поэтому мой класс выглядит так:
Заголовок класса
#ifndef LEC_H
#define LEC_H
#include <iostream>
template <typename T>
class LEC
{
public:
LEC()
{
}
void func() const;
void func2() const
{
std::cout << "Func 2" << std::endl;
}
};
#endif // LEC_H
Класс cpp
#include "lec.h"
template <typename T>
void LEC<T>::func() const
{
std::cout << "Func: " << typeid(T).name() << std::endl;
}
template class LEC<float>;
template class LEC<double>;
Последние две строки файла cpp позволяют мне использовать func()
, потому что я явно создаю экземпляр этого шаблона класса для этих двух типов. Когда я использую этот шаблон класса в программе, я могу использовать любой тип, если я не вызываю func()
:
#include "lec.h"
int main()
{
LEC<float> a;
LEC<double> b;
a.func2();
a.func();
b.func2();
b.func();
LEC<char> c;
c.func2();
return 0;
}
Но поскольку компилятор недоступен для включения func()
в класс LEC
с типом char
, я не могу выполнить c.func()
, иначе я получу ошибку компилятора:
undefined reference to `LEC::func() const'
Это упрощение моего реального кода. Однако в моем коде, когда я использую LEC<char> c
для создания экземпляра класса, я получаю сообщение об ошибке без вызова каких-либо методов, только путем создания класса.
Редактировать Cmake выглядит так:
add_library(lec_lib SHARED lec.cpp lec.h)
add_executable(lec_main main.cpp)
target_link_libraries(lec_main lec_lib)
Следовательно, скомпилированная библиотека связана с исполняемым файлом.
Редактировать 2
Не предлагайте такие ответы, как Почему шаблоны могут быть реализованы только в файле заголовка, поскольку я уже знаю, что шаблон должен быть доступен компилятору при создании экземпляра класса для нового типа. У меня другой вопрос. Почему я могу создать экземпляр типа, для которого доступны не все реализации шаблона, если я не использую конкретные методы класса, для которых реализация шаблона не предоставляется во время создания экземпляра (в примере случая func()
)
Редактировать 3
Что касается предположения, что это дубликат Что такое ошибка неопределенной ссылки / неразрешенного внешнего символа и как ее исправить?. Опять же, у меня другой вопрос. Я ищу ответы о том, почему в этом примере я могу создать экземпляр LEC<char>
, когда LEC<char>::func()
не отображается для компилятора при компиляции основной программы. И в том случае, если это невозможно сделать и требуется связать L3C<char>::func()
, как узнать, почему требуется привязка метода, пока он не используется (что происходит в моем реальном коде).
Нет, это то же самое, вы забыли скомпилировать два файла cpp и связать их с двумя объектными файлами.
Пожалуйста, попробуйте еще раз открыть этот вопрос. Я дал понять, что он отличается от предложенных дубликатов.
Это ни в коем случае не дубликат упомянутых постов. У OP возникает конкретная проблема, почему его компилятор запрашивает определение никогда не используемой функции.
apalomer: это может быть политика вашего конкретного компилятора, который хочет, чтобы все члены были определены. С clang ++ ваши файлы компилируются и работают нормально. Вы пробовали реализовать func () в заголовке? Если код не работает для определенного параметра шаблона, но никогда не используется, он все равно может компилироваться.
@apalomer Вы не вызываете c.func () в main (), где и происходит сбой. С этим добавлением он не работает как с g ++, так и с clang ++ на моей машине. Я бы сказал, просто не делай этого.
Я прочту еще раз более внимательно этот пост, который вы упомянули, но я думаю, что у меня другой вопрос.