Например у меня есть Test.h
в котором определен шаблон класса Test
и в Test.cpp
определены методы и конструкторы класса причем неявным образом,а вот уже где нибудь в main.cpp
я инициализирую Test<int> testValue
. Ничего не сработает, так как компилятор не знает, как определить мои Type
в Test.cpp
. Как можно "схитрить" ( Не используя дополнительного третьего файла типа .inl
или что нибудь еще)
Test.h
#ifndef Test
#define Test
template <class Type>
class Test
{
private:
Type value;
public:
Test(Type valueOfUser);
Type getValue();
};
#endif // Test
Test.cpp
#include "Test.h"
template <typename Type> Test<Type>::Test(Type valueOfUser): value(valueOfUser) {}
template <typename Type> Type Test<Type>::getValue () { return value; }
main.cpp
#include "Test.h"
intt main()
{
Test<int> test;
test.getValue();
return 0;
}
Есть один способ, но неудобный.
В test.cpp
можно явно инстанцировать class Test
для Type = int
, добавив в конец файла:
template class Test<int>;
Неудобство в том, что в .cpp
файле вы должны перечислить все наборы шаблонных аргументов, с которыми планируете использовать класс.
Это - самое последнее средство. Намного лучше будет послушать @Harry и просто держать дефиниции шаблонных функций в заголовочных файлах.
Уж сколько раз твердили миру... (с)
Не помещайте определения шаблонных функций/классов в отдельные .cpp-файлы. Размещайте все только в заголовочных файлах - иначе инстанцирования не происходит, вот и имеем, что имеем.
Совет от Страуструпа (A Tour of C++, adv. 7-6):
Раздельной компиляции шаблонов нет: вы должны включать с помощью директивы #include определения шаблонов в каждую единицу трансляции, которая их использует.
Вот подумайте сами - откуда при компиляции файла Test.cpp компилятору знать, что (с каким параметром шаблона) будет инстанцироваться в другом файле?
А в этом другом файле (main.cpp) - откуда знать, как инстанцировать шаблон, если нет доступа к коду реализации?
Обходной путь - указать в файле реализации шаблона явное инстанцирование необходимых типов
template class Test<конкретный_тип>;
возможен, но очень уж он неудобный - в следующий раз в main.cpp
понадобится класс для нового типа, и надо будет тут же вносить его в test.cpp
. Еще хуже, если какой-то тип станет ненужен, но будет продолжать инстанцироваться и линковаться.
Во-первых, неработоспособность вашего подхода никак не связана с тем, что "компилятор не знает, как определить мои Type в Test.cpp". Вы продолжаете это повторять из вопроса в вопрос, но никакого отношения к сути проблемы это не имеет.
Во-вторых, возможность силой "заставить" что-то работать в таком варианте у вас есть: через явное инстанцирование ваших определений в .cpp
файле для тех типов, с которыми ваш шаблон используется в программе. Но это в общем случае является нецелевым использованием возможности явного инстанцирования.
Вся суть шаблонов заключается в том, что компилятор должен сам автоматически определять, какие версии ваших шаблонных сущностей нужны в программе и генерировать их автоматически. Для этого нужно, чтобы все определения шаблонов выли видны везде, а не прятались в каком-то .cpp
файле. Возможность явного инстанцирования существует в языке в первую очередь для оптимизации этого процесса, а не для того, чтобы заменять автоматическое инстанцирование на ручное.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Изучаю C++Буду очень признателен за любую помощь
Если к одному сигналу подключены множество слотов, то в каком порядке оны вызываются?
Недавно появился снэпшот Qt 513, в котором у QImage стал доступен формат QImage::Format_Grayscale16
Попалась следующая задачаИмеется входное значение частоты Fin и выходное Fout