Автор
|
Тема: Шаблоны. В чем проблема?
|
Animal |
опубликован 06-01-2002 03:27 MSK
Не могу понять, в чем дело. Итак, есть вот такая простая программа: // main.cpp#include "a.h" void main () { A<int> a; a.Hello (); } // a.h
template <class T> class A { public: void Hello (); }; // a.cpp
#include "a.h" template <class T> void A <T> :: Hello () { } При линковке (VC++ 6.0) выдается такое сообщение: main.obj : error LNK2001: unresolved external symbol "public: void __thiscall A<int>::Hello(void)" (?Hello@?$A@H@@QAEXXZ) Debug/111.exe : fatal error LNK1120: 1 unresolved externals В чем дело? Если объявление класса и реализацию поместить в один файл - все ок, как только пытаюсь разъединить - линковщик перестает находить код определения класса. Заранее спасибо!
|
eyes
|
опубликован 06-01-2002 06:41 MSK
Шаблоны вещь конечно удобная, но даже Страуструп предупреждает: "сабж опасен для вашего здоровья" :)Дело в том, что позаботится о реализации конкретной версии класса из шаблона должен компилятор, что он вряд ли сделает, т.к. компилируя main.cpp он ничего не знает о файле a.cpp, и реализацию A<int>::Hello() просто пропускает (неплохо было бы хотябы ворнинг получить, ну да ладно). Приходится файл a.cpp удалить нафиг(поп, а файло a.h разбавить определениями функций-членов: // a.h template <class T> class A { public: void Hello () { return; // ну или что там... будет } }; Короче, макро они по своей сути, точнее макро++ |
Animal
|
опубликован 06-01-2002 15:05 MSK
Т.е. как я понимаю это диагноз VC++? Потому как подобная реализация нормальна с т.з. третьей редакции Страутсрупа. Например, на gcc программа в (1) - линкуется. Только вот, в a.h, перед объявлением шаблона, необходимо export поставить. |
Gaper
|
опубликован 06-01-2002 15:25 MSK
Ежели так хочется шаблон на два файла растащить, попробой include... Только зачем? |
Animal
|
опубликован 06-01-2002 15:31 MSK
Не дело прихоти - "растащить" шаблон. Это (на мой взгляд) совершенно нормальная ситуация, и не вижу ничего противоестественного в такой реализации.А что подразумевается под "#include..." ? ведь в a.cpp есть строка #include "a.h" ? |
Gaper
|
опубликован 06-01-2002 16:31 MSK
Извини, глупая идея... Хотя проверил, работает (ещё бы ей не работать :)...Короче, переворачиваем всё с ног на голову, и не в cpp h включаем, а наоборот. И не в начало h, а в конец. Получаем два файла, что и требовалось доказать. Только надо в settings/general cpp поставить галочку exclude file from build, в этом-то весь изврат... Ты же не сказал сразу, зачем тебе два файла :) |
Animal
|
опубликован 06-01-2002 19:26 MSK
Да, выход конечно. Т.е. мы таким образом "говорим" компилятору, что у нас все в одном! Согласен, спасибо.Но вот однако, с "теоретической" т.з., описанная первоначально схема - должна работать. Или я не прав? |
Flex Ferrum
|
опубликован 08-01-2002 10:06 MSK
С теоретической - да. Но практически такая схема еще нигде не реализована (на сколько мне известно). |
ADK
|
опубликован 08-01-2002 10:39 MSK
Помнится, для Borland C++ 5.0 рекомендовали использовать typedef для того, чтобы компилятор построил шаблон. Просто тип определяешь и всё. Подробности не помню. |