В моей DLL у меня есть шаблон класса и второй класс, полученный из экземпляра этого шаблона. Оба класса должны быть экспортированы и использоваться в других DLL. Компилятором является Visual Studio 2013. Я хочу, чтобы код шаблона создавался ровно в одной единице трансляции, поэтому я использую явное создание экземпляров.
Код в DLL1 распределяется следующим образом. Шаблон базового класса:
// In BaseTemplate.h:
#pragma once
template<typename T>
class BaseTemplate
{
public:
T foo(T t);
};
// declare explicit instantiation
extern template class BaseTemplate < int >;
// In BaseTemplate.cpp:
#include "BaseTemplate.h"
// template method definition
template<class T>
T BaseTemplate<T>::foo(T t)
{
return t;
}
// explicit instantiation and export
template class __declspec(dllexport) BaseTemplate < int >;
Производный класс:
// In Derived.h:
#pragma once
#include "BaseTemplate.h"
#ifdef DLL1_EXPORTS // this is predefined in DLL1
#define DLL1_API __declspec(dllexport)
#else
#define DLL1_API __declspec(dllimport)
#endif
class DLL1_API Derived : public BaseTemplate < int >
{
public:
void bar();
};
Теория заключалась в том, что оператор extern предотвращает создание экземпляров во всех единицах трансляции, кроме BaseTemplate.cpp, где выполняется явное создание экземпляров. Однако я получаю следующее предупреждение (которое рассматривается как ошибка в моем проекте и, таким образом, прерывает сборку):
1> basetemplate.h(19): warning C4661: 'int BaseTemplate<int>::foo(T)' :
1> no suitable definition provided for explicit template instantiation request
1> with
1> [
1> T=int
1> ]
1> basetemplate.h(15) : see declaration of 'BaseTemplate<int>::foo'
Похоже, что экспорт производного класса запускает создание экземпляра, игнорируя оператор extern. Если я удалю макрос экспорта из класса Derived, DLL1 скомпилируется без предупреждения (но очевидно, что другие библиотеки DLL не смогут связать). Если я агрегирую член типа BaseTemplate в классе Derived вместо наследования, он тоже работает (даже с экспортом).
Как я могу объединить явное создание экземпляров шаблона и экспортированные производные классы в Visual Studio?