Шаблонные функции C++

Модератор: Модераторы разделов

Ответить
Аватара пользователя
devilr
Сообщения: 3667
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Шаблонные функции C++

Сообщение devilr »

Доброго времени суток!
Есть класс, описанный полностью в одном файле:

Код: Выделить всё

// это вспомогательный класс, нет смысла его выносить отдельно
class Foo
{

};

class TestClass
{
public:
    explicit TestClass() {}
    virtual ~TestClass() {}

    template<typename T>
    void f_test(void) {}
};
Требуется запустить из другого класса функцию f_test. Делаем:

Код: Выделить всё

    TestClass *tc = new TestClass();
    tc->f_test<Foo>();
    delete tc;
Всё работает.
Однако, если класс testClass раскидать по двум файлам (cpp и hpp) то, при попытке сборки, выскочит ошибка: undefined reference to `void TestClass::f_test<Foo>()'
Почему так?
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20792
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Шаблонные функции C++

Сообщение Bizdelnick »

devilr писал(а):
22.08.2021 21:31
Однако, если класс testClass раскидать по двум файлам (cpp и hpp) то, при попытке сборки, выскочит ошибка: undefined reference to `void TestClass::f_test<Foo>()'
Почему так?
Как именно раскидать? Все шаблоны должны быть доступны там, где они инстанциируются. Если Вы перенесли определение шаблона в cpp, а инклюдите hpp, то компилятор его не найдёт.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3667
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Шаблонные функции C++

Сообщение devilr »

Bizdelnick писал:
23.08.2021 00:06
Как именно раскидать?
Как обычно. Описание класса в hpp, само тело в cpp.
Bizdelnick писал:
23.08.2021 00:06
Все шаблоны должны быть доступны там, где они инстанциируются. Если Вы перенесли определение шаблона в cpp, а инклюдите hpp, то компилятор его не найдёт.
Похоже, что именно так. Попробовал перенести тело функции в hpp, убрав его из cpp - работает. Хотя, как то это неуклюже.
Может есть более изящное решение?
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20792
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Шаблонные функции C++

Сообщение Bizdelnick »

devilr писал(а):
23.08.2021 09:12
как то это неуклюже
С шаблонами всегда так.
Добавлено (11:25):
devilr писал(а):
23.08.2021 09:12
Может есть более изящное решение?
Можно использовать явное инстанциирование шаблона в том же модуле, где он определён, но у меня пальцы не поворачиваются назвать это более изящным решением.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3667
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Шаблонные функции C++

Сообщение devilr »

Bizdelnick писал:
23.08.2021 11:12
Можно использовать явное инстанциирование шаблона в том же модуле, где он определён, но у меня пальцы не поворачиваются назвать это более изящным решением.
А это как? Можете пример привести?
P.S. Мне код в hpp не нравится тем, что он будет 100500 раз собираться. Ровно столько, сколько "инклюдится" сам hpp. По той же причине, мне не нравятся языки типа C# - крупные проекты собираются/пересобираются слишком долго и толком с этим ничего не сделать.
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20792
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Шаблонные функции C++

Сообщение Bizdelnick »

Я ж не плюсовик ни разу, могу в синтаксисе ошибиться. Как-то наподобие

Код: Выделить всё

template void f_test<TestClass *>(void);
Но лучше в поиск с запросом «explicit instantiation».
И да, это потребуется делать для каждого типа, что убивает весь смысл использования шаблона.
Добавлено (11:59):
devilr писал(а):
23.08.2021 11:42
Мне код в hpp не нравится тем, что он будет 100500 раз собираться.
Есть такое дело, да. Есть и лекарство от него — PCH (precompiled headers), но это тоже то ещё уродство.
Но Вы что, думаете, STL и прочие библиотеки шаблонов как-то по-другому работают?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
devilr
Сообщения: 3667
ОС: Mandriva => Gentoo (~amd64)
Контактная информация:

Re: Шаблонные функции C++

Сообщение devilr »

Bizdelnick писал:
23.08.2021 11:53
И да, это потребуется делать для каждого типа, что убивает весь смысл использования шаблона.
Это да. Результатом будет 100500 вышеупомянутых строчек, что убьёт сам шаблон. Я думал, что вы предложите что-то такое, новое... :)
Добавлено (12:04):
Bizdelnick писал:
23.08.2021 11:53
Но Вы что, думаете, STL и прочие библиотеки шаблонов как-то по-другому работают?
Они, хотя бы, в явно виде это не показывают. :D
Мудрость приходит с возрастом.
Иногда возраст приходит один.
Эхо разума
Спасибо сказали:
Ответить