Создание шаблонных классов в проекте библиотеки классов Переполнение стека

У меня есть проект библиотеки классов C ++, который обычно используется другими проектами C ++. Чтобы иметь возможность использовать классы внутри моего проекта библиотеки классов, я написал файл заголовка, как в примере, приведенном ниже

#pragma once
#ifdef MYLIB
# define MYLIB_EXPORT __declspec(dllexport)
#else
# define MYLIB_EXPORT __declspec(dllimport)
#endif

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

MyClass.h

template<class T>
class MYLIB_EXPORT MyClass
{
void myMethod();
// ...
}

template<class T>
void MyClass::myMethod()
{
// ...
}

В этом случае я получаю ошибки компиляции, говорящие «определение функции dllimport не разрешено». Я знаю, что вызывает проблему, и я понимаю это. Другие проекты, использующие мой проект библиотеки классов, преобразуют ключевое слово MYLIB_EXPORT в __declspec (dllimport). Поэтому они ожидают, что методы MyClass будут определены в DLL. Но затем компилятор видит определение в заголовке.

Как я могу преодолеть эту ситуацию и быть в состоянии экспортировать мои классы шаблона, которые определены в моем проекте библиотеки классов?

2

Решение

Необоснованные шаблоны не могут быть скомпилированы напрямую — они генераторы кода, поэтому они фактически переводятся в двоичные инструкции только тогда, когда они создаются; по этой причине вы не можете экспортировать шаблон «в двоичном виде», как если бы это была «обычная» функция / класс (с другой стороны, по крайней мере, теоретически вы можете экспортировать экземпляр шаблона).

Короче говоря: просто оставьте шаблоны в заголовке для включения клиентами библиотеки.

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

4

Другие решения

Просто удалите MYLIB_EXPORT утверждение по шаблону класса. Затем вы можете определить функции класса вне класса (но все еще в *.h или же *.hpp файлы заголовков).

MyClass.h

    template <typename T>
class MyClass    // MYLIB_EXPORT removed
{
void myMethod();
// ...
};

template <typename T>
void MyClass<T>::myMethod()
{
// ...
}

Я получил эту проблему. После долгого времени я понял, что удаление MYLIB_EXPORT исправило это. Надеюсь, что этот ответ сэкономит время другим 🙂

0