Объявление прототипа шаблонной функции с++

У меня имеется реализация шаблонной функции в одном файле, каким образом я могу объявить прототип этой функции, чтобы она стала доступна в текущем файле?

Более точно: зачем может потребоваться декларация шаблонной функции без тела, такая как template<typename T> T inc(const T&);?


Ответы (1 шт):

Автор решения: Pak Uula

Судя по комментариям, ТС интересуется, почему C++ дозволяет декларацию шаблона функции без тела.

Когда у шаблона тело есть, то всё понятно. В момент первого использования шаблона компилятор сгенерирует для него тело. Если же в шаблоне тела нет, то что будет?

Ответ: компилятор ничего не сгенерирует. Он запомнит точку, в которой использовался шаблон, и на этапе линковки постарается найти для него тело с нужной сигнатурой. Тело может быть получено либо через инстанциацию полного шаблона, либо через специализацию неполного.

Пример.

Заголовочный файл t.hpp:

template<typename T> T F(const T x); // { return x+1; }
template<typename T> T G(const T x); // { return 2*x; }

Файл b.cpp с телами функций:

#include "t.hpp"

template<typename T> T G(const T x) { return 2*x; }

// Специализация шаблона для случая int F<int>(cont int)
template<> int F(const int x) { return x - 1; }

static int stub() {
        int x = 10;
        return G(x); // Инстанциируется шаблон для случая int G<int>(const int)
}

В файле a.cpp оба шаблона видны без тела. Но компилятор сругается на другое.

#include "t.hpp"

int main() {
        int x = 10;
        auto y = F(x); // int F<int>(const int) -- специализация в b.cpp
        auto z = G(y);  // int G<int>(const int) -- инстанциация в b.cpp
        // Ошибка линковки: нет тела для double F<double>(const double)
        return z + F(1.0);
}

Вывод команды g++ -o some.exe a.cpp b.cpp:

/tmp/ccu0YKts.o: In function `main':
a.cpp:(.text+0x44): undefined reference to `double F<double>(double)'
collect2: error: ld returned 1 exit status

Во время линковки компилятор найдёт тело F из специализации в b.cpp, тело G<int> из инстанциации в b.cpp, а тело G<double> не найдёт, ибо этот шаблон нигде ни использовался, ни инстанциировался.

ИМХО, шаблон без тела - это хождение по граблям, стреляющим разрывным патроном прямо в пятку, но логике стандарта не противоречит.

→ Ссылка