Неразрешенные внешние элементы с явными шаблонными экземплярами. Что такое синтаксис объявления? - PullRequest
4 голосов
/ 23 марта 2010

Вот несколько упрощенных кодов, демонстрирующих мою проблему.

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

Объявления функций:

// *** template.h ***
int square (int x);
double square (double x);

Определения:

// *** template.cpp ***
#include "template.h"

// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
    return x*x;
}

// explicit instantiations
template int square (int x);
template float square (float x);

И пример использования:

// *** main.cpp ***

#include <iostream>
using namespace std;

#include "template.h"

int main (void)
{
    cout << square(2) << endl;
    cout << square(2.5) << endl;
}

Попытка скомпилировать приводит к ошибкам ссылки, примерно:

main.obj: неразрешенный внешний символ "int square (int)", на который ссылается функция main

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

Каков синтаксис для (прямого) объявления явных экземпляров шаблона, пожалуйста? Я не хочу пересылать объявление определения шаблона или перемещать определение шаблона в файл заголовка.

Для чего бы это ни стоило, у меня есть обходной путь, который заключается в использовании функций-оберток, добавляющих следующее к вышеуказанным файлам:

// *** template.cpp ***

// ...

// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }

Это компилируется и работает как положено. Тем не менее, это кажется мне взломом. В C ++ должно быть что-то более элегантное, чем это, и синтаксис шаблона.

Любая помощь или советы будут высоко оценены.

Ответы [ 2 ]

5 голосов
/ 23 марта 2010

Вам нужно объявить шаблон функции в своем заголовке:

template <typename T>
T square(T x);

Как теперь, вы объявляете две нешаблонные функции в заголовке, которые никогда не определяются.

1 голос
/ 22 мая 2012

Нет другого способа, если вы хотите скрыть шаблон из файла заголовка. Вы должны иметь функции-оболочки, потому что int square (int x); не имеет такого же искажения имени, как template int square (int x);, а C ++ не предлагает вам способ изменить это.

Вы можете проверить , как отличается смешивание имен в Visual Studio в качестве примера.

...