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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шаблоны и указатели 
:(
    Опции темы
neocpp
Дата 21.1.2013, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Код

#include <iostream>

template <class T>
void foo(T x, int size)
{
    for(int i = 0; i < size; ++i)
        std::cout << x[i] << " ";
}

int main()
{
    const int size = 5;
    int arr[size] = {1,3,5,7,9};
    
    foo(arr, size);
    
    return 0;
}

В этом коде, как я понимаю, на основе  шаблона генерируется функция типа:
Код

void foo(int* x, int size)

Потому что T заменилось на int*.

Тогда вопрос, почему если шаблон сделать таким:
Код

void foo(T* x, int size)

то функция работает по прежнему? На мой взгляд после замены T на int* должна получиться несуразица типа:
Код

void foo(int** x, int size)

PM MAIL   Вверх
xvr
Дата 21.1.2013, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(neocpp @  21.1.2013,  16:07 Найти цитируемый пост)
то функция работает по прежнему?

Потому что в первом случае T подставилось как int*, а во 2м - как int (без звездочки). Результат получился одинаковым - void foo(int* x, int size);

PM MAIL   Вверх
neocpp
Дата 21.1.2013, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(xvr @  21.1.2013,  16:17 Найти цитируемый пост)
а во 2м - как int (без звездочки)


Судя по тому, как работает функция, да. Но почему именно так происходит? Я же передал в функцию аргумент типа int* а не int...
PM MAIL   Вверх
xvr
Дата 21.1.2013, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(neocpp @  21.1.2013,  16:26 Найти цитируемый пост)
Я же передал в функцию аргумент типа int* а не int... 

Вы просто вызвали функцию. Аргументы шаблона (в функции) выводятся из спецификации параметров, а не берутся из первых попавшихся параметров, и не задаются явно  smile 
Ваша спецификация функции была void foo(T* x, int size), а вызов void foo(int* x, int size), откуда следует, что T это int, т.к. указатель уже присутствовал в формальном параметре, и следовательно он в шаблонный тип T не попал.

Если вы явно попробуете вызвать такую функцию с шаблонным параметром int*, то вы получите ошибку:
Код

template<class T>
void func(T* x, int size);

int main()
{
    const int size = 5;
    int arr[size] = {1,3,5,7,9};
    
    foo<int*>(arr, size);
    
    return 0;
}
 
PM MAIL   Вверх
mes
Дата 21.1.2013, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(neocpp @  21.1.2013,  15:26 Найти цитируемый пост)
 Но почему именно так происходит?

потому что путаете ваш х и Т.
http://liveworkspace.org/code/4rnQ4D$0


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


Новичок



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

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



Спасибо, попробую разобраться, в книге вроде бы дальше подробнее этот момент объяснен. Но пока я не совсем понял механизм, что и куда подставляется и как создается конкретный вариант функции.
PM MAIL   Вверх
mes
Дата 21.1.2013, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



если явно указаны типы шаблона, то тип берется из этого указания, иначе включается механизм детекции.  При детекции выбирается подходящая функция и по ней детектируется тип.. 
так  в случае:
Код

template<T> void fn(T *):

при передачe int *,  "формируется" void fn(int *); где Т детектируется как int.

а  в случае:
Код

template<T> void fn(T):

при передачe int *,  также "формируется" void fn(int *); но Т детектируется как int*. 


Это сообщение отредактировал(а) mes - 21.1.2013, 23:05


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


Эксперт
****


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

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



neocpp, в вашем (первом) случае вывод типа основывается лишь на одном: у типа должен быть operator[](int)
под этот тип подходят указатели на int и более сложные типы, имеющие упомянутую функцию, например std::vector
http://codepad.org/b4nakONH

во втором случае указатель присутствует явно, операция [] ему тоже соответствует, но уже как явному указателю. 
(и что-то типа vector уже не передашь)

а чтобы тип вывелся как int** требуется двойное разыменование - **x или x[i][j] и т.п.
PM MAIL   Вверх
mes
Дата 22.1.2013, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(baldina @  22.1.2013,  01:40 Найти цитируемый пост)
 в вашем (первом) случае вывод типа основывается лишь на одном: у типа должен быть operator[](int)

"вывод типа"  в данном контексте совсем не подходит...  smile  smile

Добавлено через 33 секунды
Цитата(baldina @  22.1.2013,  01:40 Найти цитируемый пост)
а чтобы тип вывелся как int** требуется двойное разыменование - **x или x[i][j] и т.п. 

в теле функции ?!  smile 


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


Эксперт
****


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

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



хотел прояснить, но видимо только запутал))
конечно не из тела, а из фактического параметра. параметр у меня за кадром остался

и в первой части - не вывод, конечно, а соответствие
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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