Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Шаблоны и указатели


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

Код

#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)

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

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

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


Судя по тому, как работает функция, да. Но почему именно так происходит? Я же передал в функцию аргумент типа int* а не int...

Автор: xvr 21.1.2013, 17:21
Цитата(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;
}
 

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

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

Автор: neocpp 21.1.2013, 19:06
Спасибо, попробую разобраться, в книге вроде бы дальше подробнее этот момент объяснен. Но пока я не совсем понял механизм, что и куда подставляется и как создается конкретный вариант функции.

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

template<T> void fn(T *):

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

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

template<T> void fn(T):

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

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

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

а чтобы тип вывелся как int** требуется двойное разыменование - **x или x[i][j] и т.п.

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

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

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

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

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

и в первой части - не вывод, конечно, а соответствие

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)