Шаблоны и указатели

 
0
 
C++
ava
neocpp | 21.01.2013, 17: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)
Ответы (9)
ava
xvr | 21.01.2013, 16:17 #
Цитата (neocpp @  21.1.2013,  16:07 findReferencedText)
то функция работает по прежнему?

Потому что в первом случае T подставилось как int*, а во 2м - как int (без звездочки). Результат получился одинаковым - void foo(int* x, int size);
ava
neocpp | 21.01.2013, 16:26 #
Цитата (xvr @  21.1.2013,  16:17 findReferencedText)
а во 2м - как int (без звездочки)


Судя по тому, как работает функция, да. Но почему именно так происходит? Я же передал в функцию аргумент типа int* а не int...
ava
xvr | 21.01.2013, 17:21 #
Цитата (neocpp @  21.1.2013,  16:26 findReferencedText)
Я же передал в функцию аргумент типа 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;
}
 
ava
mes | 21.01.2013, 17:26 #
Цитата (neocpp @  21.1.2013,  15:26 findReferencedText)
 Но почему именно так происходит?

потому что путаете ваш х и Т.
http://liveworkspace.org/code/4rnQ4D$0
ava
neocpp | 21.01.2013, 19:06 #
Спасибо, попробую разобраться, в книге вроде бы дальше подробнее этот момент объяснен. Но пока я не совсем понял механизм, что и куда подставляется и как создается конкретный вариант функции.
ava
mes | 21.01.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*.
ava
baldina | 22.01.2013, 02:40 #
neocpp, в вашем (первом) случае вывод типа основывается лишь на одном: у типа должен быть operator[](int)
под этот тип подходят указатели на int и более сложные типы, имеющие упомянутую функцию, например std::vector
http://codepad.org/b4nakONH

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

а чтобы тип вывелся как int** требуется двойное разыменование - **x или x[i][j] и т.п.
ava
mes | 22.01.2013, 20:22 #
Цитата (baldina @  22.1.2013,  01:40 findReferencedText)
 в вашем (первом) случае вывод типа основывается лишь на одном: у типа должен быть operator[](int)

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

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

в теле функции ?!  smile 
ava
baldina | 22.01.2013, 20:33 #
хотел прояснить, но видимо только запутал))
конечно не из тела, а из фактического параметра. параметр у меня за кадром остался

и в первой части - не вывод, конечно, а соответствие
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
  mes   xvr   baldina   neocpp
advanced
Отправить