Если вы просто объявили шаблон в файле .h, а реализация вместо этого - в файле .cpp, то это ошибка, которую вы получите, потому что компилятор C ++ работает по одному модулю компиляции за раз.Когда компилятор находит ваш код, вызывающий только что объявленную функцию шаблона, он будет предполагать, что конкретная реализация будет выполнена каким-либо другим модулем компиляции (компилятор не может знать, где найти файл .cpp для этой функции... компилятор видит только один .cpp и все включенные .h одновременно).
Если параметры шаблона находятся в хорошо известном списке, вы можете просто запросить все известные вам явные реализации, которые понадобятсядля программы в .cpp.
Например, если у вас есть шаблонная функция
template<typename T>
T foo(T x)
{
...
}
, и вы знаете, что вам просто понадобятся int foo(int);
и string foo(string);
, тогда хорошоиспользуйте только объявление в .h, при условии, что вы также добавите две строки в .cpp, говоря:
template<> int foo(int);
template<> string foo(string);
Делая это, вы сообщаете компилятору о том, какую специализацию строить.Если впоследствии вы в конечном итоге используете другие специализации (например, vector<int> foo(vector<int>)
), то вы также должны добавить это явное создание экземпляра в файл .cpp шаблона.
Однако в вашем примере, глядя на код, я предполагаю, что вы незаранее не знаю, какой тип событий будет определен, и поэтому это явное создание экземпляра невозможно.
Другое решение - просто поместить всю реализацию шаблона в файл .h вместо отделения объявления от реализации.Это иногда может быть нетривиальным, потому что требует, чтобы вы раскрыли больше деталей реализации, вероятно, вводя больше зависимостей.