LIREN
@LIREN
Пунктумофоб

Почему не работает функция?

Учу c++, параллельно пробую разные плюшки языка, и столкнулся с необъяснимой для меня проблемой:

Ссылка на неразрешенный внешний символ "int __cdecl functions::Test<int>(int)" (??$Test@H@functions@@YAHH@Z) в функции main.

Source.cpp:

#include <iostream>
#include <string>
#include "Functions.h"

int main()
{
	functions::Test(1);
}

Functions.h:

#pragma once
#include <iostream>
#include <string>

namespace functions
{
	// Вывод в консоль
	void PrintMessage(std::string var);
	void PrintMessage(char var);
	void PrintMessage(int var);
	void PrintMessage(double var);

	template <typename T>
	T Test(T var);
}

Functions.cpp:

#include "Functions.h"

namespace functions
{
	// Вывод в консоль
	void PrintMessage(std::string var)
	{
		std::cout << var;
	}
	void PrintMessage(char var)
	{
		std::cout << var;
	}
	void PrintMessage(int var)
	{
		std::cout << var;
	}
	void PrintMessage(double var)
	{
		std::cout << var;
	}

	template <typename T>
	T Test(T var)
	{
		std::cout << var;
	}
}

Перегрузка функций работает(но не хочу её использовать), но template - нет!
Что происходит?
  • Вопрос задан
  • 141 просмотр
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Проблема в том, что код функций из шаблонов генерируется по мере надобности.
Вот встретил компилятор где-то Test<int> - и начинает создавать функцию для int.
Но в единице трансляции с Functions.cpp он этого не встретил и ничего не генерирует. А когда он компилирует Source.cpp он может только сгенерировать декларацию, но не определение функции. Ведь он видит хедер, но не что написано в Functions.cpp.

Поэтому, если весь шаблон определять в .h файле то компилятор сможет сгенерировать что ему надо всегда.

Второй варинат решения проблемы - в Functions.cpp указать компилятору, что шаблон будет использоватся с такиим-то типами:
using Test<int>;

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

Обычно минусы тут перевешивают плюсы и шаблоны всегда целиком пишут в хедерах. Но это не единственный враиант. Неправда, что шаблоны должны целиком находится в хедерах.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Шаблоны надо реализовывать в *.h файле.
Ответ написан
Комментировать
MvcBox
@MvcBox
Software Engineer [C/C++/JS(for Node.js)/etc]
Имплементация шаблонных функций должна находиться в заголовочном файле
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы