Внешнее (в .cpp) определение функции класса-шаблона
От: Аноним  
Дата: 03.12.05 14:04
Оценка:
Составим вот такой код:

tclass.h:
#ifndef FFFKJHDFJKHDF
#define FFFKJHDFJKHDF

template<int v> class Type2Int {public: enum{classType = v}; };
typedef Type2Int<11> Texture2D;

template<class T, class TexType>
class CTypedTexture {};

template<class T>
class CTypedTexture<T, Texture2D> {
public:
    CTypedTexture();
    ~CTypedTexture();

};

#endif


tclass.cpp
#include "tclass.h"

template<class T>
CTypedTexture<T,Texture2D>::CTypedTexture() {};
template<class T>
CTypedTexture<T,Texture2D>::~CTypedTexture() {};


mail.cpp
#include "tclass.h"

void main () {
    CTypedTexture<Texture2D,Texture2D> d;
}


Получаем на выходе ошибку:
LINK : warning LNK4224: /PDBTYPE is no longer supported;  ignored
main.obj : error LNK2019: unresolved external symbol "public: __thiscall CTypedTexture<class Type2Int<11>,class Type2Int<11> >::~CTypedTexture<class Type2Int<11>,class Type2Int<11> >(void)" (??1?$CTypedTexture@V?$Type2Int@$0L@@@V1@@@QAE@XZ) referenc
ed in function _main
main.obj : error LNK2019: unresolved external symbol "public: __thiscall CTypedTexture<class Type2Int<11>,class Type2Int<11> >::CTypedTexture<class Type2Int<11>,class Type2Int<11> >(void)" (??0?$CTypedTexture@V?$Type2Int@$0L@@@V1@@@QAE@XZ) reference
d in function _main
Debug/ttest.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.


Как правильно определить члены класса-шаблона в .cpp?

Если просто скопировать определения из tclass.cpp в tclass.h, то все компилиться будет, но тогда проект приходиться каждый раз полностью перекомпилировать, при измении кода определения в .h.

Плиз, помогите чайнику!
Re: Внешнее (в .cpp) определение функции класса-шаблона
От: _nn_ www.nemerleweb.com
Дата: 03.12.05 14:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Составим вот такой код:


А>tclass.h:

А>
А>#ifndef FFFKJHDFJKHDF
А>#define FFFKJHDFJKHDF

А>template<int v> class Type2Int {public: enum{classType = v}; };
А>typedef Type2Int<11> Texture2D;

А>template<class T, class TexType>
А>class CTypedTexture {};

А>template<class T>
А>class CTypedTexture<T, Texture2D> {
А>public:
А>    CTypedTexture();
А>    ~CTypedTexture();

А>};

А>#endif
А>


А>tclass.cpp

А>
А>#include "tclass.h"

А>template<class T>
А>CTypedTexture<T,Texture2D>::CTypedTexture() {};
А>template<class T>
А>CTypedTexture<T,Texture2D>::~CTypedTexture() {};
А>


А>mail.cpp

А>
А>#include "tclass.h"

А>void main () {
А>    CTypedTexture<Texture2D,Texture2D> d;
А>}
А>


А>Получаем на выходе ошибку:

А>
А>LINK : warning LNK4224: /PDBTYPE is no longer supported;  ignored
А>main.obj : error LNK2019: unresolved external symbol "public: __thiscall CTypedTexture<class Type2Int<11>,class Type2Int<11> >::~CTypedTexture<class Type2Int<11>,class Type2Int<11> >(void)" (??1?$CTypedTexture@V?$Type2Int@$0L@@@V1@@@QAE@XZ) referenc
А>ed in function _main
А>main.obj : error LNK2019: unresolved external symbol "public: __thiscall CTypedTexture<class Type2Int<11>,class Type2Int<11> >::CTypedTexture<class Type2Int<11>,class Type2Int<11> >(void)" (??0?$CTypedTexture@V?$Type2Int@$0L@@@V1@@@QAE@XZ) reference
А>d in function _main
А>Debug/ttest.exe : fatal error LNK1120: 2 unresolved externals
А>Error executing link.exe.
А>


А>Как правильно определить члены класса-шаблона в .cpp?


А>Если просто скопировать определения из tclass.cpp в tclass.h, то все компилиться будет, но тогда проект приходиться каждый раз полностью перекомпилировать, при измении кода определения в .h.


А>Плиз, помогите чайнику!



Определение шаблонов должно быть в одной единицы трансляции.
А по существу: перенесите имплементацию шаблона в заголовочный файл.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Внешнее (в .cpp) определение функции класса-шаблона
От: Кодт Россия  
Дата: 03.12.05 14:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как правильно определить члены класса-шаблона в .cpp?


Есть такое волшебное слово "экспорт шаблонов" (поиском по сайту: export template).
В VC71 не поддерживается.

А>Если просто скопировать определения из tclass.cpp в tclass.h, то все компилиться будет,


И это является самым правильным и переносимым решением

А>но тогда проект приходиться каждый раз полностью перекомпилировать, при измении кода определения в .h.


При изменении файла с определением экспортных шаблонов — тоже придётся всё перекомпилировать.
Так что, если бы даже это было возможно, то тебя не спасло бы.

Отсюда мораль: постарайся отладить свои шаблоны, чтобы потом к ним как можно реже возвращаться.
Перекуём баги на фичи!
Re[2]: Внешнее (в .cpp) определение функции класса-шаблона
От: Аноним  
Дата: 03.12.05 15:08
Оценка:
окей...

Теперь вот такой код:

tclass.h:
#ifndef FFFKJHDFJKHDF
#define FFFKJHDFJKHDF

template<int v> class Type2Int {public: enum{classType = v}; };
typedef Type2Int<11> Texture2D;

template<class TexType>
class CTypedTexture {};

template<>
class CTypedTexture<Texture2D> {
public:
    CTypedTexture();
    ~CTypedTexture();

};

CTypedTexture<Texture2D>::CTypedTexture() {}
CTypedTexture<Texture2D>::~CTypedTexture() {}

#endif


main.cpp
#include "tclass.h"

void main ()
{
    CTypedTexture<Texture2D> d;
}



Получаем:
tclass.obj : error LNK2005: "public: __thiscall CTypedTexture<class Type2Int<11> >::CTypedTexture<class Type2Int<11> >(void)" (??0?$CTypedTexture@V?$Type2Int@$0L@@@@@QAE@XZ) already defined in main.obj
tclass.obj : error LNK2005: "public: __thiscall CTypedTexture<class Type2Int<11> >::~CTypedTexture<class Type2Int<11> >(void)" (??1?$CTypedTexture@V?$Type2Int@$0L@@@@@QAE@XZ) already defined in main.obj
Debug/ttest.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
Re[3]: Внешнее (в .cpp) определение функции класса-шаблона
От: _nn_ www.nemerleweb.com
Дата: 03.12.05 17:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>окей...


А>Теперь вот такой код:


А>tclass.h:

А>
А>#ifndef FFFKJHDFJKHDF
А>#define FFFKJHDFJKHDF

А>template<int v> class Type2Int {public: enum{classType = v}; };
А>typedef Type2Int<11> Texture2D;

А>template<class TexType>
А>class CTypedTexture {};

А>template<>
А>class CTypedTexture<Texture2D> {
А>public:
А>    CTypedTexture();
А>    ~CTypedTexture();

А>};

А>inline CTypedTexture<Texture2D>::CTypedTexture() {}
А>inline CTypedTexture<Texture2D>::~CTypedTexture() {}

А>#endif
А>


А>main.cpp

А>
А>#include "tclass.h"

А>void main ()
А>{
А>    CTypedTexture<Texture2D> d;
А>}
А>



А>Получаем:

А>
А>tclass.obj : error LNK2005: "public: __thiscall CTypedTexture<class Type2Int<11> >::CTypedTexture<class Type2Int<11> >(void)" (??0?$CTypedTexture@V?$Type2Int@$0L@@@@@QAE@XZ) already defined in main.obj
А>tclass.obj : error LNK2005: "public: __thiscall CTypedTexture<class Type2Int<11> >::~CTypedTexture<class Type2Int<11> >(void)" (??1?$CTypedTexture@V?$Type2Int@$0L@@@@@QAE@XZ) already defined in main.obj
А>Debug/ttest.exe : fatal error LNK1169: one or more multiply defined symbols found
А>Error executing link.exe.
А>
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Внешнее (в .cpp) определение функции класса-шаблона
От: Кодт Россия  
Дата: 03.12.05 22:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>tclass.h:

< ... >
А>CTypedTexture<Texture2D>::CTypedTexture() {}
А>CTypedTexture<Texture2D>::~CTypedTexture() {}

А вот определения функций и статических членов полных специализаций — можно (а то и нужно) выносить в .cpp, потому что компилятор их воплотит, а линкер найдёт (и хорошо бы, чтоб он их нашёл в количестве 1 шт. на проект).
Или объявлять их __declspec(any) (MS-specific: инструкция линкеру, чтобы выбрал любой из найденных, а не ругался на многократное определение); тот же эффект приносит слово inline.
Перекуём баги на фичи!
Re: Внешнее (в .cpp) определение функции класса-шаблона
От: Pavel Chikulaev Россия  
Дата: 05.12.05 06:21
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>tclass.cpp

А>
А>#include "tclass.h"

А>template<class T>
А>CTypedTexture<T,Texture2D>::CTypedTexture() {};
А>template<class T>
А>CTypedTexture<T,Texture2D>::~CTypedTexture() {};


template class CTypedTexture<int, Texture2D>;
template class СTypedTexture<float, Texture2D>;
template class СTypedTexture<dummy, Texture2D>;
//явное инстаницирование шаблонов, теперь чтобы использовать этой шаблон с типами int, float, dummy в других единицах трансляции достаточно включить tclass.h
А>
Re[2]: Внешнее (в .cpp) определение функции класса-шаблона
От: Lorenzo_LAMAS  
Дата: 05.12.05 11:07
Оценка:
как раз так сделать нельзя
14.7/5
Of course, the code must be complete enough to compile and link.
Re[3]: Внешнее (в .cpp) определение функции класса-шаблона
От: Pavel Chikulaev Россия  
Дата: 05.12.05 11:40
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>как раз так сделать нельзя

L_L>14.7/5
Для ленивых и у кого стандарта нет:

No program shall explicitly instantiate any template more than once, both explicitly instantiate and explicitly
specialize a template, or specialize a template more than once for a given set of template-arguments.
An implementation is not required to diagnose a violation of this rule.


А что собственно нельзя? Код шаблона находится в Cpp файле, явно инстанцировать из других единиц трансляции все равно не получится... Или дело в параметре Texture2D?

И зачем такое ограничение в стандарте? Сложно что-ли?
Re[4]: Внешнее (в .cpp) определение функции класса-шаблона
От: Lorenzo_LAMAS  
Дата: 05.12.05 12:14
Оценка:
PC>А что собственно нельзя? Код шаблона находится в Cpp файле, явно инстанцировать из других единиц трансляции все равно не получится... Или дело в параметре Texture2D?

Дело в h файле который включается в несколько cpp файлов, что приведет к нарушению требования однократного явного инстанцирования. А делается это так — h файл содержит объявление шалона, cpp содержит определение и явное инстанцирование, пользовательский код включает заголовок. Естественно, что параметризация будет ограничено теми типами, которыми явно инстанцировали в том cpp
Of course, the code must be complete enough to compile and link.
Re[5]: Внешнее (в .cpp) определение функции класса-шаблона
От: Pavel Chikulaev Россия  
Дата: 05.12.05 12:16
Оценка: +1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

PC>>А что собственно нельзя? Код шаблона находится в Cpp файле, явно инстанцировать из других единиц трансляции все равно не получится... Или дело в параметре Texture2D?


L_L>Дело в h файле который включается в несколько cpp файлов, что приведет к нарушению требования однократного явного инстанцирования.

У меня явное инстаницирование в CPP!!!

L_L>А делается это так — h файл содержит объявление шалона, cpp содержит определение и явное инстанцирование, пользовательский код включает заголовок. Естественно, что параметризация будет ограничено теми типами, которыми явно инстанцировали в том cpp


http://rsdn.ru/Forum/Message.aspx?mid=1521125&amp;only=1
Автор: Pavel Chikulaev
Дата: 05.12.05
В этот раз читаем внимательно.
Re[6]: Внешнее (в .cpp) определение функции класса-шаблона
От: Lorenzo_LAMAS  
Дата: 05.12.05 12:22
Оценка: :)
Извини, не разглядел, увидев инстанцирования и

достаточно включить tclass.h


радостно метнулся писать
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.