2010-03-23 7 views
4

Вот несколько упрощенных кодов для демонстрации проблемы, которая у меня есть.Unresolved externals с явным шаблоном. Что такое синтаксис объявления?

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

объявления функций являются:

// *** 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 квадрат (целое)» ссылка в функции главного

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

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

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

// *** template.cpp *** 

// ... 

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

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

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

ответ

5

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

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

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

+1

, но это предполагает, что у вас есть больше типов avail, а не только double и int –

+0

@Ronny: Если вы попытались создать экземпляр шаблона с любыми типами, отличными от тех, для которых вы предоставили явные экземпляры в исходном файле, компиляция завершится неудачей , Если это не очевидно из декларации, было бы неплохо документировать шаблон функции, чтобы детализировать, с какими типами он может быть создан. –

+0

Как различный исходный файл (main.cpp) + заголовок знает о явных экземплярах? При связывании вы получите ошибку - возможно, не очень полезную. –

1

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

В качестве примера вы можете указать how name mingling differs in Visual Studio.