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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Расскажите про template 
:(
    Опции темы
Wowa
Дата 17.2.2005, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


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

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



Расскажите, пожалуйста, про template

Что это, для чего, и краткий пример использования.
PM WWW   Вверх
maxim1000
Дата 17.2.2005, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



пример:
дали переменную, сказали посчитать в ней количество бит, равных 1
спрашиваем, для каких типов реализовать?
ответ: char,int,void*,double

можно, конечно, написать все 4 функции и не мучаться
Код

//пример для char
int CalcOnes(char x)
{
 int result=0;
 while(x)
 {
   if(x&1)
     result++;
   x>>=1;
 }
 return result;
}

но нам хочется сделать все это одной функцией
так вот шаблоны этого НЕ позволяют smile
вместо этого шаблоны позволяют научить компилятор генерировать подобные функции, когда будет нужно:
Код

template<class T>
int CalcOnes(T x)
{
 int result=0;
 int counter;
 char *CharPtr=(char*)&x;

 for(counter=0;counter<sizeof(T);counter++)
 {
   while(x)
   {
     if(x&1)
       result++;
     x>>=1;
   }
   CharPtr++;
 }
 return result;
}

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

cout<<CalcOnes("qqq")<<"\n";//выведет количество 1 в битовом представлении указателя на строку :)

smile
а как сделать ссылку на конкретное сообщение?

Это сообщение отредактировал(а) maxim1000 - 17.2.2005, 14:32


--------------------
qqq
PM WWW   Вверх
pablo
Дата 17.2.2005, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 320
Регистрация: 12.2.2005
Где: Вильнюс, Литва

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



template - это ключевое слово С++, означающее использование шаблона.

После слова template в <типы или типовые параметры>, шаблонами могут быть не только функции, но и классы.
Как правило используется там, где надо написать алгоритм который будет работать одинакого с разными типами данных.

Вот пример использования:
// List.h: interface for the List class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_LIST_H__BC404E61_5B68_4FA2_82B5_99EB5C8DBFE5__INCLUDED_)
#define AFX_LIST_H__BC404E61_5B68_4FA2_82B5_99EB5C8DBFE5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <iostream>

using std::cout;

#include <new>
#include "ListNode.h" // ListNode class definition

template< typename NODETYPE >
class List
{

public:
List(); // constructor
~List(); // destructor
void insertAtFront( const NODETYPE & );
void insertAtBack( const NODETYPE & );
bool removeFromFront( NODETYPE & );
bool removeFromBack( NODETYPE & );
bool isEmpty() const;
void print() const;
List< NODETYPE > & operator = (const List< NODETYPE > &);
int operator < (const List< NODETYPE > &);
int numberOfElements() const;
private:
int length;
ListNode< NODETYPE > *firstPtr; // pointer to first node

// utility function to allocate new node
ListNode< NODETYPE > *getNewNode( const NODETYPE & );
}; // end class List

// default constructor
template< typename NODETYPE >
List< NODETYPE >::List(): firstPtr( 0 ), length(0)
{
// empty body

} // end List constructor

// destructor
template< typename NODETYPE >
List< NODETYPE >::~List()
{
if ( !isEmpty() )
{ // List is not empty

ListNode< NODETYPE > *currentPtr = firstPtr;
ListNode< NODETYPE > *tempPtr;

while ( currentPtr != 0 )
{ // delete remaining nodes
tempPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
delete tempPtr;

} // end while

} // end if


} // end List destructor

// insert node at front of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtFront( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value );

if ( isEmpty() ) // List is empty
{
firstPtr = newPtr;
length++;
}
else
{ // List is not empty
newPtr->nextPtr = firstPtr;
firstPtr = newPtr;
length++;
} // end else

} // end function insertAtFront

// insert node at back of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtBack( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr = getNewNode( value );

if ( isEmpty() ) // List is empty
{
firstPtr = newPtr;
length++;
}
else
{ // List is not empty
while(firstPtr)
{
firstPtr = firstPtr->nextPtr;
}

firstPtr->nextPtr = newPtr;
firstPtr = newPtr;
length++;

} // end else

} // end function insertAtBack

// delete node from front of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromFront( NODETYPE &value )
{
if ( isEmpty() ) // List is empty
return false; // delete unsuccessful

else
{
ListNode< NODETYPE > *tempPtr = firstPtr;

if ( firstPtr == lastPtr )
firstPtr = lastPtr = 0;
else
firstPtr = firstPtr->nextPtr;

value = tempPtr->data; // data being removed
delete tempPtr;
length--;
return true; // delete successful

} // end else

} // end function removeFromFront

// delete node from back of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromBack( NODETYPE &value )
{
if ( isEmpty() )
return false; // delete unsuccessful

else
{
ListNode< NODETYPE > *tempPtr;

if ( firstPtr->nextPtr )
firstPtr = 0;
else
{
ListNode< NODETYPE > *currentPtr = firstPtr;
while(firstPtr->nextPtr)
{
firstPtr = firstPtr->nextPtr;
}

// locate second-to-last element
while ( currentPtr->nextPtr != lastPtr )
currentPtr = currentPtr->nextPtr;

lastPtr = currentPtr;
currentPtr->nextPtr = 0;

} // end else

value = tempPtr->data;
delete tempPtr;
length--;
return true; // delete successful

} // end else

} // end function removeFromBack

// is List empty?
template< typename NODETYPE >
bool List< NODETYPE >::isEmpty() const
{
return firstPtr == 0;

} // end function isEmpty

// return pointer to newly allocated node
template< typename NODETYPE >
ListNode< NODETYPE > *List< NODETYPE >::getNewNode(const NODETYPE &value )
{
return new ListNode< NODETYPE >( value );

} // end function getNewNode

// display contents of List
template< typename NODETYPE >
void List< NODETYPE >::print() const
{
if ( isEmpty() )
{
cout << "The list is empty\n\n";
return;

} // end if

ListNode< NODETYPE > *currentPtr = firstPtr;

cout << "The list is: ";

while ( currentPtr != 0 ) {
cout << currentPtr->data << ' ';
currentPtr = currentPtr->nextPtr;

} // end while

cout << "\n\n";

} // end function print
template< typename NODETYPE >
int List< NODETYPE >::numberOfElements() const
{
return length + 1;
}
template < typename NODETYPE>
List< NODETYPE> & List< NODETYPE>:: operator = (const List< NODETYPE> &a)
{
while(!this ->isEmpty())
{
int value;
this ->removeFromBack(value);
}

ListNode< NODETYPE > *currentPtr = a.firstPtr;

while(currentPtr != 0)
{
this -> insertAtBack(currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
return *this;
}

template < typename NODETYPE>
int List< NODETYPE>:: operator < (const List< NODETYPE > &a)
{
if(length < a.length)
return 1;
return 0;
}

#endif // !defined(AFX_LIST_H__BC404E61_5B68_4FA2_82B5_99EB5C8DBFE5__INCLUDED_)


Добавлено @ 14:35
говоря проще, то шаблоны исбвляют программиста, от перегузки функций для разных типов и написания классов для близких типов


--------------------
Первый блин всегда похож на сферу, иногда бывает и куб.
PM MAIL ICQ   Вверх
Sardar
Дата 17.2.2005, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

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



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

По другому это работает в Java5 и C#, там все шаблоны приводятся к общему типу Object. Компилятор следит какие типы ты кладёшь в шаблон(ую функцию, класс и т.п.). В момент использования компилятор сам добавляет привидение типа к Object и обратно. Таким образом мы реально имеем всего одну функцию(метод) работающий со многими типами обьектов.

Проблема: примитивы должны обращатся в обьекты оболочки(boxing), это убивает производительность. Вывод: а на кой хранить примитивы в контейнерах, мы ведь ООП используем smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Wowa
Дата 17.2.2005, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


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

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



Цитата(pablo @ 17.2.2005, 12:32)
говоря проще, то шаблоны исбвляют программиста, от перегузки функций для разных типов и написания классов для близких типов


и все? для чего они еще могут быть полезны?
PM WWW   Вверх
chipset
Дата 18.2.2005, 06:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

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



Цитата(Admin @ 17.2.2005, 04:30)
и все? для чего они еще могут быть полезны?

Вроде бы ни для чего.
А что мало? smile
Прикинь, надо былоб создавать для каждого класса класс...
Вообще то, желательно заглядывать в таких вопросах в Страуструпа или стандарт, там точнее всего написано.
pablo, используй плз. теги [code=cpp][/code]. Читать такую кашу глаза устают...


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Borisff2003
Дата 18.2.2005, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата

и все? для чего они еще могут быть полезны


Ну например вся STL построенна на шаблонах

Еще можешь почитать
Andrei Alexandrescu (Андрей Александреску)
Modern C++ Design (Современное проектирование на C++)
http://anatolix.naumen.ru/Books/CPlusPlus?v=fvi
--------------------
Лень, двигатель прогресса
PM MAIL WWW ICQ   Вверх
Hroft
Дата 25.2.2005, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Вот это точно. Великая книга.
Моя любимая идея оттуда - разбиение классов на стратегии: множественное наследование от параметров шаблона. Потрясающая гибкость. И еще - возможность определять, является ли тип указателем (да и много чем еще). Списки типов. В общем - Loki.
PM MAIL ICQ   Вверх
De Gray
Дата 25.2.2005, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Admin @ 17.2.2005, 15:30)
и все? для чего они еще могут быть полезны?

Определения является ли интерфейс желаемым интерфейсом(по сдвигу в VTable).
Осталось только добавить, что с шаблонами каждый вызов функции превращается в довольно изощренное и долгое действо, что, есстессно, убивает производительность
-- немного более изящный выход -- частичная спецификация. Не говоря уже о том, что вынос шаблона в отдельный модуль является довольно изощренной проблемой настроек многих компиляторов.
--------------------
Извяните, шо мы к вас за поможите обращаимси.
PM MAIL   Вверх
maxim1000
Дата 25.2.2005, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

шаблоны не влияют на процесс вызова функции: они пропадают сразу после компиляции


--------------------
qqq
PM WWW   Вверх
bel_nikita
Дата 25.2.2005, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

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



chipset
Цитата
Вообще то, желательно заглядывать в таких вопросах в Страуструпа или стандарт, там точнее всего написано
Hroft
Цитата
еще - возможность определять, является ли тип указателем (да и много чем еще). Списки типов. В общем - Loki.

Только беда в том, что не фсе компиляторы поддерживают стандарт на фсе 100% smile

Цитата
Осталось только добавить, что с шаблонами каждый вызов функции превращается в довольно изощренное и долгое действо, что, есстессно, убивает производительность
При современных процессорах и мощности системы вцелом - незначительный проигрышь smile Мы проигрываем в производительности 0,5%, сжираем память, а в проектировании и разработке кода можем выиграть до 100% smile (Загнул конешна, но ладно smile )
Ну и конечно, зависит под что затачиваем софт smile



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0740 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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