2013-09-20 3 views
0

Я пробовал рекомендацию here. У меня есть следующий класс с шаблонными функциями членов, определенных в реализации следующим образом:C++ templated Member function linker ошибки в клиентском приложении

заголовка (с директивой импорта компилятора DLL оцененного в __declspec(dllimport) в клиентском приложении):

class __declspec(dllimport) A { 
    ... 
    template<typename T> bool func(T&) const; 
} 

реализация:

template<typename T> bool A::func(T&) {...} 

Из-за некоторых ограничений я не могу определить его заголовок. В автономной библиотеке я не получаю ошибок сборки. Но в клиентском приложении, построенный на той же платформе, используя тот же компилятор (x64 VS100), ошибка линкера я получаю:

error LNK2019: unresolved external symbol bool "public: bool __cdecl A::func(...)" 

Цените любые идеи по этому поводу. Благодаря!

+2

Такой же ответ, как [абсолютно каждый другой] (http://stackoverflow.com/q/495021/596781) Вопрос «мой код шаблона не связан» на этом сайте? –

ответ

0

Ваш код шаблона не будет сгенерирован до тех пор, пока вы его не создадите с использованием некоторого типа данных. Для каждого типа данных компилятор генерирует другой код.

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

Если вам нужно только небольшое количество вариантов шаблона, скажем int и float, то вы можете объявить явные экземпляры шаблона. Эти объявления приводят к тому, что компилятор действительно выводит код шаблона для данных данных, независимо от того, нужны они или нет в компиляционной единице. Затем вам также нужно добавить инструкции dllimport/dllexport (в случае компиляторов Windows Visual Studio) для экс-импорта этого кода в/из DLL.

Подробнее об этом можно, конечно, найти в других обсуждениях и документации.

+0

Спасибо @zijlstra: Объявление в заголовке не вариант для меня. У меня возникли проблемы с пониманием того, почему он строит отлично (та же платформа - x64 vs100) при создании на месте (символ экспорта dll); но генерирует ошибку компоновщика только с клиента (символ импорта dll). Кроме того, я не уверен, что понял, что вы имеете в виду, когда вы сказали добавить инструкцию dllimport/dllexport для «этого кода»; У меня есть класс. Вы имеете в виду, мне нужны эти символы, даже для деклараций о создании? –

+0

Если вы хотите больше узнать об этом, например, [здесь] (http://stackoverflow.com/questions/666628/importing-explicitly-instantiated-template-class-from-dll) –

0

Убедитесь, что ваша реализация выполнена в том же заголовке (или она взята с каким-либо другим утверждением #include) в качестве определения класса. В этом случае он должен работать.

+0

Из-за некоторых практических соображений это для меня это не вариант. Думаю, я должен был это разъяснить. –