Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Stl: в чем плюсы шаблонов? 
:(
    Опции темы
Lazin
Дата 27.5.2009, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(math64 @  27.5.2009,  09:26 Найти цитируемый пост)
хоть и применены шаблоны, но основной код шаблона не размножается

с чего ты это взял? будут точно так-же созданы N реализаций шаблона smile 
PM MAIL Skype GTalk   Вверх
math64
Дата 27.5.2009, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(Alca @  27.5.2009,  09:33 Найти цитируемый пост)
А если функция может использовать только один тип данных, стоит ли использовать шаблон?

Иногда стоит - если ты эту функцию объявил, но не используешь в данном проекте, то она не будет включена в исполняемый файл.
А если функция обычная, то она будет всегда включена в исполняемый файл, даже если не нужна (если файл с функцией исключить нельзя, поскольку в нём есть нужные функции и он используется в другом проекте, где все функции нужны)
PM   Вверх
Lazin
Дата 27.5.2009, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(Alca @  27.5.2009,  09:33 Найти цитируемый пост)
А если функция может использовать только один тип данных, стоит ли использовать шаблон? 

нет, какой смысл в шаблоне, если все-равно будет только один вариант функции?
PM MAIL Skype GTalk   Вверх
math64
Дата 27.5.2009, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(Lazin @  27.5.2009,  09:43 Найти цитируемый пост)
с чего ты это взял? будут точно так-же созданы N реализаций шаблона

Я сказал: основной код шаблона не размножается. Большинство методов будет взято из базового класса или будут inline-методами,
вызывающими метод базового класса с кастингом аргументов и результата. Фактически размножатся только конструктор и деструктор.
PM   Вверх
Alca
Дата 27.5.2009, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Цитата

нет, какой смысл в шаблоне, если все-равно будет только один вариант функции?

Она же не будет включена в исполняемый файл.


--------------------
PM WWW ICQ Skype Jabber   Вверх
zim22
Дата 27.5.2009, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(math64 @  27.5.2009,  09:48 Найти цитируемый пост)
Фактически размножатся только конструктор и деструктор.

Из книжечки "Программирование на С++". Коплиен

Цитата

используя идиому косвенного шаблона можно в полной мере использовать возможности параметризации без затрат на дублирование кода в разных версиях шаблонного класса.
...
Далее приведено простое приложение, использующее параметризованный тип Set, который в свою очередь использует параметризованный тип List. Хотя в программе встречаются две разновидности Set, для поддержки обеих создается только одна специализация List

main.cpp
Код

Set<int> foo;
Set<double> bar;

foo.add(1);
foo.add(2);
cout << foo.get() << endl;
cout << foo.get() << endl;

bar.add(3.0);
bar.add(4.2);
cout << bar.get() << endl;
cout << bar.get() << endl;

List.h
Код

#ifndef LIST_H
#define LIST_H

template <class T> class List;

template <class T> class ListItem {
  friend class List<T>;
private:
  ListItem<T> *next;
  const T item;
  ListItem(ListItem<T> *n, const T &i) : item(i), next((ListItem<T>*)n) { }
};

template <class T>
class List {
public:
  void sort(); // сортировка списка "на месте"
  void put(const T &t) { head = new ListItem<T>(head, t); }
  T get() { // выборка из начала списка
    T retval = head->item;
    ListItem<T> *temp = head;
    head = head->next;
    delete temp;
    return retval;
  }
  int element(const T &t) const { return 0; } // проверка принадлежности
  // ...                         // другие операции
  int size() const;              // количество элементов
  List() : head(0) { }
private:
  ListItem<T> *head;
};
#endif // LIST_H

Set.h
Код

#ifndef SET_H
#define SET_H

#include "List.h"

class SetBase {
  friend class ErsatzListElement;
private:
  virtual int comparelt(const void*, const void*) const = 0;
  virtual int compareeq(const void*, const void*) const = 0;
};

class ErsatzListElement {
  // Класс не параметризуется: это означает,
  // что одна специализация шаблона List обслуживает
  // все специализации Set
public:
  const void *rep;
  int operator<(const ErsatzListElement &l) const {
    return theSet->comparelt(this, &l);
  }
  int operator==(const ErsatzListElement &l) const {
    return theSet->compareeq(this, &l);
  }
  ErsatzListElement(const void *v = 0) : rep(v) { }
  ErsatzListElement(const SetBase *s, void *v = 0) : theSet(s), rep(v) { }
private:
  const SetBase *theSet;
};

template <class T> 
class Set : private SetBase {
public:
  void add(T t2) {
    if (!exists(t2)) {
      ErsatzListElement t(this, new T(t2)); 
      rep.put(t);
    }
  }
  T get() {
    ErsatzListElement l = rep.get();
    return *((T*)(l.rep));
  }
  void remove(const T&);
  int exists(const T &e) {
    ErsatzListElement t(this, (T*)&e);
    return rep.element(t);
  }
  Set<T> Union(const Set<T>&) const;
  Set<T> Intersection(const Set<T>&) const;
  int size() const { return rep.size(); }
  void sort() { rep.sort(); }
  Set();
private:
  List<ErsatzListElement> rep;
  int comparelt(const void *v1, const void *v2) const {
    const T *t1 = (const T*)v1;
    const T *t2 = (const T*)v2;
    return *t1 < *t2;
  }
  int compareeq(const void *v1, const void *v2) const {
    const T *t1 = (const T*)v1;
    const T *t2 = (const T*)v2;
    return *t1 == *t2;
  }
};
template <class T>
Set<T>::Set() { }

#endif // SET_H


Это сообщение отредактировал(а) zim22 - 27.5.2009, 10:20


--------------------
PM MAIL   Вверх
Alexeis
Дата 27.5.2009, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



  Есть и минусы, шаблон это общее решение. Общее решение всегда не быстрее грамотного частного решения. Шаблон должен использовать только общие возможности всех типов для которых он предназначен, тогда как специальный класс может использовать все возможности того типа с которым он работает.
  Для сравнения создайте вектор, например из 1024 байтов и добавьте еще элемент так чтобы было перераспределение и сделайте аналогичные операции руками при помощи new для выделения памяти/memcpy для копирования элементов/memset для инициализации нулями. Думаю скорость будет выше раза в два.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
ilyuha
Дата 27.5.2009, 10:12 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 10.7.2007

Репутация: нет
Всего: нет



Цитата(Alca @  27.5.2009,  09:48 Найти цитируемый пост)
Она же не будет включена в исполняемый файл. 

 smile Кто она? Код ф-ии? smile А куда он денется?

PM MAIL   Вверх
Lazin
Дата 27.5.2009, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(Alexeis @  27.5.2009,  10:10 Найти цитируемый пост)
Для сравнения создайте вектор, например из 1024 байтов и добавьте еще элемент так чтобы было перераспределение и сделайте аналогичные операции руками при помощи new для выделения памяти/memcpy для копирования элементов/memset для инициализации нулями. Думаю скорость будет выше раза в два. 

бессовестная ложь smile 
PM MAIL Skype GTalk   Вверх
Cтpaнник
Дата 27.5.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 12.10.2008
Где: Россия, Санкт-Пет ербург

Репутация: нет
Всего: нет



Цитата(Alexeis @ 27.5.2009,  10:10)
Есть и минусы, шаблон это общее решение. Общее решение всегда не быстрее грамотного частного решения. [...]
  Для сравнения создайте вектор, например из 1024 байтов и добавьте еще элемент [...] Думаю скорость будет выше раза в два.

Это верно. Однако, не следует преждевременно оптимизировать - во всяком случае, раньше, чем профилировщик и/или пользователи не обратили ваше внимание на низкую производительность.

Готовый шаблон из STL нужно - только использовать. Собственный вектор - нужно сначала написать, потом отладить, убедиться в отсутствии ошибок (написать юнит-тесты хотя бы), и только потом - использовать. Скорость разработки зачастую является более значимым фактором, чем потеря 1-2% производительности приложения в целом, которых никто не заметит.

Это сообщение отредактировал(а) Cтpaнник - 27.5.2009, 10:27
PM MAIL   Вверх
azesmcar
Дата 27.5.2009, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Alexeis @  27.5.2009,  10:10 Найти цитируемый пост)
Для сравнения создайте вектор, например из 1024 байтов и добавьте еще элемент так чтобы было перераспределение и сделайте аналогичные операции руками при помощи new для выделения памяти/memcpy для копирования элементов/memset для инициализации нулями. Думаю скорость будет выше раза в два.

с это чего вдруг? smile 
PM   Вверх
Lazin
Дата 27.5.2009, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



после инстанциирования, алгоритм работы вектора сведется к тому, что квалифицированный программист может написать вручную, лишних действий там выполняться не будет
для некоторых параметров многие шаблоны специализированы, к примеру специализация std:swap для векторов не копирует элементы, а просто меняет местами указатели, или vector<bool> на самом деле не вектор элементов типа bool smile

Добавлено через 3 минуты и 4 секунды
Цитата(Alexeis @  27.5.2009,  10:10 Найти цитируемый пост)
тогда как специальный класс может использовать все возможности того типа с которым он работает

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

Добавлено через 11 минут и 26 секунд
Цитата(Cтpaнник @  27.5.2009,  10:26 Найти цитируемый пост)
Это верно

нет! smile 
Alexis - не понимает о чем он говорит, его представление о шаблонах заканчивается на параметризированых типах, a-la дженерики в .NET. С помощью шаблонов можно делать намного больше и не платить за это уменьшением производительности. Некоторые идиомы с++ вообще не реализуемы без шаблонов.
PM MAIL Skype GTalk   Вверх
Alexeis
Дата 27.5.2009, 11:17 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(azesmcar @  27.5.2009,  09:28 Найти цитируемый пост)
с это чего вдруг?

  Проведите исследование, зайдите под дебагом в код. При копировании байтиков что будет делать вектор? Использовать 8 бит своего регистра, предварительно очищать верхнюю часть регистра, короче будет порядка 4-5 ассемблерных операций на перенос всего одного байта, тогда как memcpy возьмет цельный регистр разрядности процессора закинет в него сразу 4 элемента (8 элементов) и за одну операцию перекинет его в другой участок памяти. А если глянуть на код наращивания так вообще диву даешься. 
  В том то и дело, что счет идет не на 1-2%, а на 100-200%

Цитата(Lazin @  27.5.2009,  09:30 Найти цитируемый пост)
можно специализировать шаблонный класс для определенных типов и оптимизировать некоторые аспекты его работы, а для других типов использовать обобщенную реализацию

  Этим мало кто занимается, потому что в тот момент когда пишешь шаблон как правило не знаешь всех типов к которым он будет применим. Начинаешь проектировать общее. В последствии менять код шаблона уже не желательно, так как это может повлиять на стабильность его работы.
  Кроме того шаблонный код ориентирован максимально на статическое связывание внутри программы, это уменьшает гибкость в рантайме, ухудшают модульность, увеличивают время компиляции. Попробуйте экспортировать шаблон из DLL. При каждой перекомпиляции модуля будут перекомпилированы все шаблоны которые он использует, не просто заголовки, а их реализация. Можно сказать что шаблонный класс это недокласс.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Lazin
Дата 27.5.2009, 11:29 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(Alexeis @  27.5.2009,  11:17 Найти цитируемый пост)
Проведите исследование, зайдите под дебагом в код. При копировании байтиков что будет делать вектор? Использовать 8 бит своего регистра, предварительно очищать верхнюю часть регистра, короче будет порядка 4-5 ассемблерных операций на перенос всего одного байта, тогда как memcpy возьмет цельный регистр разрядности процессора закинет в него сразу 4 элемента (8 элементов) и за одну операцию перекинет его в другой участок памяти. А если глянуть на код наращивания так вообще диву даешься. 

Опять-же, бессовестная ложь smile 
Посмотри что получится в релизе, с оптимизациями и отключенными runtime проверками. И чем тебе не нравится код наращивания?

Цитата(Alexeis @  27.5.2009,  11:17 Найти цитируемый пост)
Этим мало кто занимается, потому что в тот момент когда пишешь шаблон как правило не знаешь всех типов к которым он будет применим.

я привел пример smile 
PM MAIL Skype GTalk   Вверх
azesmcar
Дата 27.5.2009, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Alexeis @  27.5.2009,  11:17 Найти цитируемый пост)

  Проведите исследование, зайдите под дебагом в код. При копировании байтиков что будет делать вектор? Использовать 8 бит своего регистра, предварительно очищать верхнюю часть регистра, короче будет порядка 4-5 ассемблерных операций на перенос всего одного байта, тогда как memcpy возьмет цельный регистр разрядности процессора закинет в него сразу 4 элемента (8 элементов) и за одну операцию перекинет его в другой участок памяти. А если глянуть на код наращивания так вообще диву даешься. 
  В том то и дело, что счет идет не на 1-2%, а на 100-200%


непременно проведу..но вы сперва скажите какая из реализаций СТЛ ведет себя так а то я подозреваю что на нее наткнутся будет весьма сложно. smile 
Цитата

insert
Notes: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all
the iterators and references before the insertion point remain valid. If an exception is thrown other than
by the copy constructor or assignment operator of T there are no effects.

покажите мне в стандарте - где сказано что вектор должен копировать используя
Цитата

8 бит своего регистра

и
Цитата

предварительно очищать верхнюю часть регистра


это дело того - кто реализовывал СТЛ. Стандарт не требует вызывать копи-конструкторы во время наращивания вектора, следовательно можно реализовать это и с помощью memcpy.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0707 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.