Задать вопрос
@communistic_sistema
Биохимик, но в программировании немного шарю

Почему шаблон выдает ошибку при включении заголовка в .cpp файл?

У менять есть решение разделенное на 2 проекта.
Проект 1 (exe) содержит main.cpp и test.h.
Проект 2 (lib) содержит больше файлов, но проблему рассмотрим на 2 из них, stack.h, stack.ipp.
Проект 1 собирается после проекта 2 и имеет от него зависимость (дополнительные каталоги включаемых проектов и т.д. настроены)
main.cpp включает test.h
test.h включает stack.ipp
stack.ipp включает stack.h
Все работает
Но стоит в проекте 2 создать .cpp файл и включить в него любой stack файл - получаю ошибки
Например:
stack.h(6,22): error C2760: синтаксическая ошибка: непредвиденный элемент "||". Ожидается "выражение"
, что ссылается на этот код:
template<typename T>
concept dyn_memory_limit = !(
		std::is_void_v<T> ||			//can`t return void
		std::is_unbounded_array_v<T>	//cant manage T[]
	) &&
	std::is_destructible_v<T>			//will destruct all data in destructor
;

type_traits включены (в другой заголовок, что включается в stack.h) и оно слава богу (почему перестало - не ясно) перестало выдавать ошибку на std namespace, однако это не единственная ошибка - она затрагивает ВСЮ структуру шаблонную, что я объявил.

stack.h объявляет, stack.ipp определяет шаблонную структуру
(попытался разделить как в .h/.cpp делается)
При этом, если я сую объявление и определение в один файл (сразу в шаблоне определяю), то такой ошибки нет

Использую VS2022, С++ 20 и С17 в обоих проектах

В чем может быть причина того, что в проекте 2 любой cpp ломает все?
  • Вопрос задан
  • 59 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Не совсем уверен, потому что кода не хватает в вопросе. Но симптом звучит как "если шаблон определяется не в том же файле, где он объявляется, то ничего не работает". Это частая ошибка на С++ с шаблонами.

Когда компилятор видит, что шаблон используется, он генерирует код с конкретной спецификацией шаблона. Но делает он это только в текущем юните трансляции. Так что если у вас шаблон определен в другом cpp файле, то компилятор эти определения не видит и не может сгенерировать их спецификацию, когда обрабатывает cpp с использованием шаблона. А когда дело доходит до cpp с шаблоном, то компилятор не видит, где и как шаблон используется и тоже не генерирует никакой спецификации.

Поэтому надо или шаблон объявлять и опеределять в хедере, чтобы оперделения были везде, или в cpp с определениями указать спецификацию для всех используемых варинтов шаблона. Вроде
using my_template<int>;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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