Задать вопрос
Dyikot
@Dyikot

Использование шаблона в многофайловом проекте, как реализовано в vector например?

Из-за того что если реализации методов находятся в .cpp файле то надо прописывать что-то типо template class Class_Name<type>; для каждого типа. Но правильно ли я понимаю что в том же vector все реализации в .h файле? Может последовать их примеру?
  • Вопрос задан
  • 606 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 2
@MarkusD Куратор тега C++
все время мелю чепуху :)
Основным постулатом работы с шаблонами является то, что определение шаблона должно быть достижимо из места его инстанцирования.

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

В первом случае, когда используемое в .cpp файле определение шаблона вписано в том же .cpp файле, определение шаблона будет достижимо только в данном .cpp файле и больше нигде. В этом случае попытка инстанцировать шаблон в другом модуле трансляции приведет к ошибке трансляции, т.к. там определние шаблона будет уже недостижимо.
Файлы исходного кода включать через директиву #include - это дурной тон и прямой путь к нарушению ODR.

Во втором случае стоит сразу вспомнить про ODR и правила его соблюдения. В частности про то, что определения методов по месту их объявления являются встраиваемыми неявно. А если определение метода выполняется снаружи определения класса, то в виду требований к шаблонам функций и шаблонам методов, чтобы гарантировать ODR, встраиваемость определения нужно указывать уже явным образом.

Широкой практикой является разделение кода шаблонов на несколько типов файлов. В .h файлах обычно делают или объявления шаблонов функций, или определения шаблонов классов. В .hpp/.inl файлах обычно делают определения шаблонов функций и шаблонов методов.
При этом .hpp/.inl файл очень часто включается в самом низу .h файла с его объявлениями.
Моя личная рекомендация: использовать в таких случаях расширение .inl (от слова inline), т.к. для .hpp столь же широко закреплено взаимоисключающее с .h значение заголовка C++ кода. И видеть эти два расширения в одном проекте обычно бывает странно.

Вектор же, например в проекте LLVM, реализован так, что часть определений в нем сделаны по месту объявления, а часть - как внешние определения сразу после определения шаблона вектора. Все это сделано прямо в одном заголовке.
Ответ написан
Комментировать
@dima20155
you don't choose c++. It chooses you
Да, реализацию методов шаблонных классов необходимо помещать в заголовочный файл.
Вы можете использовать следующий подход, который позволит вам разделить объявление и определение

Foo.h

template <typename T>
struct MyStruct
{
    void foo(T arg);
};

#include "Foo-inl.h"


Foo-inl.h
template <typename T>
void MyStruct<T>::foo(T arg)
{
    // some code
}


Также, если вы используете специализируете шаблонный параметр в определении методов класса методов, то такие методы можно поместить в .cpp файл.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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