Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: ISO C++ forbids declaration of ‘map’ with no type  (Прочитано 43175 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« : 17-12-2010 11:47 » 

Пытаюсь въехать в шаблоны и немного недопонимаю...

Код: (C++)
#include <map>

using namespace std;

template <class A, class B, class C> class X
{
  // ...
};

template <class A, class B, class C> class Y
{
public:
  typedef X<A, B, C> X;
  typedef map<int, X*> XCollection;

};

Ошибка в отмеченной строке.

Штудирую Страуструпа и не могу найти ответ. Ну, или могз перегрузился. Объясните, пожалуйста, мою ошибку.



Добавлено через 2 минуты и 17 секунд:
Ёпрст...
Все фишка была только в том, что я не подгрузил map (в приведенном примере он есть, а у меня - нет). Однако, сообщения gcc не интуитивно понятны.

Добавлено через 3 минуты и 35 секунд:
Тогда другой вопрос: в выше приведенном примере есть X<A,B,C> и Y::X. Это идентичные типы или разные? Не будет ли у меня проблем с этим?

Например:

Код: (C++)
class Xaaa : public X<int, int, int>
{
  // ...
};

class Yaaa : public Y<int, int, int>
{
  // ...
};

Здесь Xaaa и Yaaa::X идентичны или это разные классы?
« Последнее редактирование: 17-12-2010 11:54 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 17-12-2010 12:21 » 

Цитата: RXL
есть X<A,B,C> и Y::X. Это идентичные типы или разные?
По-моему typedef - это аналог макроподстановки (не препроцессорный), поэтому название нового типа полностью эквивалентно определению. Сами X и X, конечно, разные. При этом внутри Y больший приоритет имеет ближайшее определение X в typedef, а не внешнее определение. Однако при попытке описания методов вне класса это уже будет не так, и Y::X нужно будет указывать явно.

Цитата: RXL
Здесь Xaaa и Yaaa::X идентичны или это разные классы?
Здесь классы, конечно, разные, поскольку наследование - это не переопределение через typedef. Ты можешь в оба эти класса добавить собственное разное содержание - тогда их различие станет более очевидным для тебя.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 17-12-2010 13:26 » 

RXL,

во втором примере Yaaa::X - это синоним для class X<int,int,int>, так как он унаследован из базового класса class Y<int,int,int>.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 17-12-2010 13:44 » 

Еще вопрос.

Код: (C++)
#include <map>

using namespace std;

template <class A, class B, class C> class Y
{
public:
  typedef map<int, A*> ACollection;
  typedef ACollection::const_iterator ACIterator; // или напрямую использовать ACollection::const_iterator
};

В отмеченной строке имею ошибку.

type ‘std::map<unsigned int, A*, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, A*> > >’ is not derived from type ‘Y<A, B, C>’


Я понимаю только, что не понимаю шаблонов полностью. В простых случаях трудности не возникают, а тут - даже не знаю, в какую сторону думать.
« Последнее редактирование: 17-12-2010 13:47 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 17-12-2010 14:25 » 

RXL, по-моему надо так:

Код: (C++)
typedef typename ACollection::const_iterator ACIterator;

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

Подробнее не скажу - я в этой части стандарт в деталях не изучал. Но в общем и целом это немного похоже на проблемы с макросами для препроцессора.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 17-12-2010 15:15 » 

RXL, это называется dependent name  - зависимое имя.

Фишка в том, что в С++ разрешается делать специализации шаблонов - для определенного сочетания параметров шаблонов ты можешь создать отдельный тип, который будет совсем не похож на типы, инстанциированные из общего шаблона. По этой причине С++ требует, чтобы имена типов, объявленных в шаблонах, в других шаблонах использовались с префиксом typename

Тем самым ты подсказываешь компилятору, что ты декларируешь именно тип
« Последнее редактирование: 17-12-2010 15:20 от npak » Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 18-12-2010 10:10 » 

Dimka, typename ставил, но это вызывает другую ошибку. У Страуструпа сказано, что typename нужно указывать в случаях неоднозначности интерпретации.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 18-12-2010 10:17 » 

Dimka, typename ставил, но это вызывает другую ошибку.

Да ладно - я прогнал твой пример с typename в gcc 4.3
Код: (C++)
#include <map>

using namespace std;

template <class A, class B, class C> class Y
{
    public:
          typedef map<int, A*> ACollection;
          typedef typename ACollection::const_iterator ACIterator; //  Collection::const_iterator
};

Компилируется без возражений
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 18-12-2010 10:48 » 

Заголовок скомпилировался. Набор каких-то странных ошибок. Сейчас напишу тест и посмотрим, работает ли это.

У меня gcc 4.1.2
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 18-12-2010 10:49 » 

Рома, у тебя какой компилятор? Поддержка шаблонов С++ в gcc моложе 4.3 не полностью соответствует стандарту.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 18-12-2010 13:05 » 

Код: (C++)
  1. #include <map>
  2.  
  3. using namespace std;
  4.  
  5. /* template X */
  6.  
  7. template<class A, class B> class X
  8. {
  9. protected:
  10.     A *a;
  11.     B *b;
  12.  
  13. public:
  14.     X(A *a, B *b) : a(a), b(b) { }
  15.     ~X() { }
  16. };
  17.  
  18. /* template Y */
  19.  
  20. template<class X, class A, class B> class Y
  21. {
  22. public:
  23.     typedef map<int, X*> XCollection;
  24.     typedef XCollection::iterator Iterator;
  25.  
  26. protected:
  27.     A *a;
  28.     B *b;
  29.     XCollection x;
  30.  
  31. public:
  32.  
  33.     Y(A *a, B *b) : a(a), b(b) { }
  34.     ~Y() { }
  35.     Iterator begin() { return x.begin(); }
  36.     Iterator end() { return x.end(); }
  37. };
  38.  
  39. /* ********** */
  40.  
  41. class TA
  42. {
  43. };
  44.  
  45. class TB
  46. {
  47. };
  48.  
  49. typedef X<TA, TB> _TX;
  50.  
  51. class TX : public _TX
  52. {
  53. public:
  54.     TX(TA *a, TB *b) : _TX(a, b) { }
  55. };
  56.  
  57. typedef Y<TX, TA, TB> _TY;
  58.  
  59. class TY : public _TY
  60. {
  61. public:
  62.     TY(TA *a, TB *b) : _TY(a, b) { }
  63. };
  64.  
  65. /* ********** */
  66.  
  67. int main()
  68. {
  69.     TY y();
  70.  
  71.     return 0;
  72. }

$ g++ -Wall -c tpl_class_test1.cpp
tpl_class_test1.cpp:24: error: type ‘std::map<int, X*, std::less<int>, std::allocator<std::pair<const int, X*> > >’ is not derived from type ‘Y<X, A, B>’
tpl_class_test1.cpp:24: error: expected ‘;’ before ‘Iterator’
tpl_class_test1.cpp:35: error: ‘Iterator’ does not name a type
tpl_class_test1.cpp:36: error: ‘Iterator’ does not name a type

Рома, у тебя какой компилятор? Поддержка шаблонов С++ в gcc моложе 4.3 не полностью соответствует стандарту.

Старенький - 4.1.2... Жаль
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 18-12-2010 16:23 » 

Ну я на GCC 4.2.1 (20070719) проверял...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 18-12-2010 16:58 » 

Пробую на виртуалке с FC12.

# cat /etc/issue
Fedora release 12 (Constantine)
# g++ --version
g++ (GCC) 4.4.3 20100127 (Red Hat 4.4.3-4)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# g++ -Wall -c tpl_class_test1.cpp
tpl_class_test1.cpp:24: error: type ‘std::map<int, X*, std::less<int>, std::allocator<std::pair<const int, X*> > >’ is not derived from type ‘Y<X, A, B>’
tpl_class_test1.cpp:24: error: expected ‘;’ before ‘Iterator’
tpl_class_test1.cpp:35: error: ‘Iterator’ does not name a type
tpl_class_test1.cpp:36: error: ‘Iterator’ does not name a type

GCC 4.4.3. Результат тот же.

Я вообще правильно пишу код (в посте №10) или опять чего не допонял?


Добавлено через 1 час, 2 минуты и 58 секунд:
В BCB6 компиляция прошла без проблем.
Я использовал GCC для предварительного написания и тестирования классов, а потом переносил код в BCB6 и дополнял VCL-спецификой. Видимо придется сразу в BCB6 писать и тестировать.
« Последнее редактирование: 18-12-2010 18:01 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 18-12-2010 19:04 » 

Странные вещи:

1. Наследую от созданного по шаблону класса. Переопределяю метод m2() в своем классе. Вызываю метод m1(), определенный в шаблоне и вызывающий m2(). Отладчик показывает, что мой переопределенный метод игнорируется.

2. Указываю методы в шаблоне, которые хочу переопределить, как "virtual ... = 0". Код начинает работать как надо. Смотрю в Страуструпа и вижу, что он запрещает объявлять virtual-методы в шаблоне.
« Последнее редактирование: 18-12-2010 19:19 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 18-12-2010 19:13 » 

typedef typename XCollection::iterator Iterator;
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 18-12-2010 19:18 » 

Коль, у меня без typename работает в BCB6. Его обязательно указывать?
Кстати, с typename тоже работает. Компилятор старый - тоже может отклоняться от правил.
« Последнее редактирование: 18-12-2010 19:24 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 18-12-2010 19:53 » 

RXL, ну раз без него не работает в GCC, то обязательно. Оно же ничему не мешает - чем больше, тем лучше Улыбаюсь

Цитата: RXL
1. Наследую от созданного по шаблону класса. Переопределяю метод m2() в своем классе. Вызываю метод m1(), определенный в шаблоне и вызывающий m2(). Отладчик показывает, что мой переопределенный метод игнорируется.

2. Указываю методы в шаблоне, которые хочу переопределить, как "virtual ... = 0". Код начинает работать как надо. Смотрю в Страуструпа и вижу, что он запрещает объявлять virtual-методы в шаблоне.
А вот это непонятно. Так что ли?
Код: (C++)
template<class T> class X {
protected:
  virtual void m2() = 0;
public:
  void m1() { this->m2(); }
};

class Y: public X<int> {
protected:
  void m2() { cout << "m2" << endl; }
};
И как тут обойтись без виртуальных методов? Там Страуструп заодно не советует отказаться от сочетания наследования и шаблонов?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 18-12-2010 20:00 » 

Да, Дим, пример подходящий.

Не, Старуструп в норме - я опять лажанулся: он запрещает виртуализировать член-шаблон.
Постараюсь быть внимательнее, но при неожиданно свалившемся объеме информации это бывает затруднительно.

Мне нравится эта книга, но т.к. я читаю его не всего, а использую как справочник, то порой примеров из параграфа не хватает или не понимаю.

P.S.: после скриптовых языков C++ видится довольно сложным. Вопрос привычки...
« Последнее редактирование: 18-12-2010 20:03 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 18-12-2010 20:36 » 

Цитата: RXL
Мне нравится эта книга, но т.к. я читаю его не всего, а использую как справочник, то порой примеров из параграфа не хватает или не понимаю.
А это и есть справочник Улыбаюсь Только литературно оформленный. Я его честно пытался раза 3 начинать читать как книгу - и ни разу не удалось. Самое оптимальное - читать главы по потребности (благо, перекрёстные ссылки в тексте имеются).

Цитата: RXL
после скриптовых языков C++ видится довольно сложным.
Все эти беды от строгой типизации и родовых черт C. Зато строгая типизация даёт возможность генерировать высокопроизводительный код. Так что хотя бы для более глубокого понимания программирования, по-моему, полезно познакомиться.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 19-12-2010 16:54 » 

Добил свой проектик - на BCB6 собирается на ура. Правда, у ихнего компилятора тоже не мало заскоков.

Оцениваю сокращение кода за счет выноса общих частей модулей (их у меня 9 штук по три класса) в шаблоны примерно в 10 раз, трудоемкость написания вышла примерно такая же или немного больше (без шаблонов был бы копипаст с правкой, доводкой и тестированием в каждом модуле), а вот изменять выходит много проще (только если не изменять конструкторы в шаблоне).

Подмечаю такую особенность, что если метод шаблонного класса в программе не используется, то компилятор выкидывает его из фактического класса.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 19-12-2010 18:39 » 

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

Стандарт явным образом запрещает (should not) инстанцировать сущности (методы, статические данные), которые не используются в программе, за исключением явного инстанцирования.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 19-12-2010 19:28 » 

Цитата: RXL
Подмечаю такую особенность, что если метод шаблонного класса в программе не используется, то компилятор выкидывает его из фактического класса.
А как ты это подметил?

Я тут в связи с этим задумался о раздельной компиляции и всяких финтах ушами с наследованием инстанцированных шаблонных классов...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 19-12-2010 19:35 » 


Я тут в связи с этим задумался о раздельной компиляции и всяких финтах ушами с наследованием инстанцированных шаблонных классов...

раздельная компиляция шаблонов - это поиск приключений на свою ... голову, скажем так.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #23 : 19-12-2010 20:15 » 

Dimka, в процессе тестирования: в некоторых случаях ошибки компиляции возникали только если использовать метод, в котором была ошибка.


А что вы имеете в виду под "раздельная компиляция шаблонов" и "наследованием инстанцированных шаблонных классов"?...
« Последнее редактирование: 19-12-2010 20:17 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #24 : 19-12-2010 20:33 » 

npak,
Цитата
раздельная компиляция шаблонов - это поиск приключений на свою ... голову, скажем так.

Стандартэтого делать не запрещает, просто разработчики компиляторов пока не забацали реализацию... правда когда я сморел в эту сторону последний раз на дворе был 200 год...

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

ну а наследование инстацированных шаблонных классов... я пока не понимаю, что именно ты не понимаешь))
« Последнее редактирование: 19-12-2010 20:38 от lapulya » Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #25 : 20-12-2010 04:11 » 

Dimka, в процессе тестирования: в некоторых случаях ошибки компиляции возникали только если использовать метод, в котором была ошибка.

Стандарт предписывает, для шаблонного всего, на этапе компиляции делать минимальные проверки и только того, что не зависит от параметров шаблона, естетсвенно до тех пор пока не будет инстацирования, тогда проверки, как для обычных функций
VC++ при этом пошла дальше, она вообще не проверять содержимое шаблона, если он не используется.

Как-то так.

Разделением реализации и обявления шаблона, я развлекался, нормальная практика ничего тут срашного нет, только приходится явно истанцировать шаблоны по мере необходимости, а то линковщик ругается, что нет реализации методов.
На старой работе у нас было куча кода с явным инстанцированием и раздельной реализией, так софтина собиралась быстрее и не падал компилятор. Шаблоны были очень большие и когда мы оставляли их в хедерах, то:
1. Инстанцирование происходило в каждой единице трансляции, а это отчень не быстро
2. компилятор запросто заваливался с ошибокой - алярм, достигнуто максимальное количество элементов на единицу трансляции (развернёт все методы, переменные и т.д.) - эта ошибка характерна для MS VC++ в gcc её небыло

Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #26 : 20-12-2010 04:48 » 

Антон, можешь дать пример? Я пока не врубаюсь, как можно разделить шаблон и потом применить его.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #27 : 20-12-2010 06:10 » 

так же как с обычным разделением на объявление и реализацию

main.cpp
Код: (C++)
#include "templ.h"

using namespace std;


int main()
{
    TSome<int> s;
    s.print();

    TSome<char> s2;
    s2.print();

    return 0;
}

templ.h
Код: (C++)
#ifndef TEMPL_H
#define TEMPL_H

template <typename T>
struct TSome
{
    void print();
};

#endif // TEMPL_H

templ.cpp
Код: (C++)
#include <iostream>
#include "templ.h"

template <typename T>
void TSome<T>::print()
{
    std::cout << "TSome::print()\n";
}

template class TSome<int>;
template class TSome<char>;

вот отличная книга про шаблоны:
http://books.google.com/books?id=yQU-NlmQb_UC&lpg=PP1&dq=isbn%3A0201734842&hl=ru&pg=PA135#v=onepage&q&f=false
http://www.insidecpp.ru/books/cpp_templates/

Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 20-12-2010 07:49 » 

Столько комментариев, и всё не о том, что я имел в виду Улыбаюсь

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

Вот мне и непонятно: выкидывает неиспользуемые методы линкер? Ведь компилятор работает раздельно для каждого объектного файла и заранее не может узнать, какие методы понадобятся, а какие нет.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 20-12-2010 08:10 » 

так же как с обычным разделением на объявление и реализацию

templ.cpp
Код: (C++)
#include <iostream>
#include "templ.h"

template <typename T>
void TSome<T>::print()
{
    std::cout << "TSome::print()\n";
}

template class TSome<int>;
template class TSome<char>;


Ага, вот об этом я и говорил. В результате получилось, что у тебя определены только классы TSome<int> и TSome<char>. Если добавить в main TSome<short>, то ни gcc 4.3, ни MS VC 10 не смогут слинковать. Скажут, что отсутствует символ TSome<short>::print(void)

Стандарт С++ оставляет поддержку такой схемы на откуп разработчикам. Вот как описывается инстанциирование шаблонов в стандарте (2.1 Phases of compilation, paragraph 8 )
Цитата
Each translated translation unit is examined to produce a list of required instantiations.  [Note: this may include instantiations which have been explicitly requested (14.7.2).  ] The definitions of the required templates are located.  It is implementation-defined whether the source of the translation units containing these definitions is required to be available.
« Последнее редактирование: 20-12-2010 08:12 от npak » Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines