Вывод аргументов шаблоной функции
От: Yacha Россия  
Дата: 01.06.05 14:07
Оценка:
Всем доброго времени суток!

Хотелось бы разъеснить следующую ситуацию:

template<typename T>
void foo(T t)
{
   t = 1;
}

...

int i = 0;
int &ii = i;
foo(ii);//здесь передается по значению, а хотелось бы по ссылке


Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но
почему в первом случае T не может быть int& ?
Re: Вывод аргументов шаблоной функции
От: Ignoramus  
Дата: 01.06.05 14:21
Оценка:
Здравствуйте, Yacha, Вы писали:

Y>Всем доброго времени суток!


Y>Хотелось бы разъеснить следующую ситуацию:


Y>
Y>template<typename T>
Y>void foo(T t)
Y>{
Y>   t = 1;
Y>}

Y>...

Y>int i = 0;
Y>int &ii = i;
Y>foo(ii);//здесь передается по значению, а хотелось бы по ссылке
Y>


Это почему ты так решил? Здесь передается по значению, а значение копируется через ссылку, но это уже детали, не имеющие к foo отношения.

Y>Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

Y>почему в первом случае T не может быть int& ?

Тут нет правильного или неправильного. Следует сделать так, как тебе нужно
Re: Вывод аргументов шаблоной функции
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 01.06.05 14:29
Оценка:
Здравствуйте, Yacha, Вы писали:

Y>Хотелось бы разъеснить следующую ситуацию:


Y>
Y>template<typename T>
Y>void foo(T t)
Y>{
Y>   t = 1;
Y>}

Y>...

Y>int i = 0;
Y>int &ii = i;
Y>foo(ii);//здесь передается по значению, а хотелось бы по ссылке
Y>


Y>Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

Y>почему в первом случае T не может быть int& ?

Можно явно специализировать шаблон:

int i = 0;
int &ii = i;
foo<int&>(ii);
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Вывод аргументов шаблоной функции
От: Yacha Россия  
Дата: 01.06.05 14:31
Оценка:
Здравствуйте, Ignoramus, Вы писали:

I>Здравствуйте, Yacha, Вы писали:


Y>>Всем доброго времени суток!


Y>>Хотелось бы разъеснить следующую ситуацию:


Y>>
Y>>template<typename T>
Y>>void foo(T t)
Y>>{
Y>>   t = 1;
Y>>}

Y>>...

Y>>int i = 0;
Y>>int &ii = i;
Y>>foo(ii);//здесь передается по значению, а хотелось бы по ссылке
Y>>


I>Это почему ты так решил? Здесь передается по значению, а значение копируется через ссылку, но это уже детали, не имеющие к foo отношения.


Тип T должен выводиться на основании типа аргумента t, если я не прав, то поправте меня, в приведенном случае типом аргумента является
int &



Y>>Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

Y>>почему в первом случае T не может быть int& ?

I>Тут нет правильного или неправильного. Следует сделать так, как тебе нужно
Re: Вывод аргументов шаблоной функции
От: MaximE Великобритания  
Дата: 01.06.05 14:31
Оценка: 6 (2)
Yacha wrote:

> Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

> почему в первом случае T не может быть int& ?

[temp.deduct.call] 14.8.2.1 Deducing template arguments from a function call
...
2 If P is not a reference type:
...
If P is a cv qualified type, the top level cv qualifiers of P s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction.


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: Вывод аргументов шаблоной функции
От: Аноним  
Дата: 01.06.05 14:45
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Yacha wrote:


>> Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

>> почему в первом случае T не может быть int& ?

ME>

ME>[temp.deduct.call] 14.8.2.1 Deducing template arguments from a function call
ME>...
ME>2 If P is not a reference type:
ME>...
ME>If P is a cv qualified type, the top level cv qualifiers of P s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction.

Для ясности
F(P1 A1, P2 A2, ...PN AN) — шаблонная функция в общем виде
На сколько я понимаю в первом случае P не является ссылочным типом. Тогда выделенный тобой фрагмент стандарта не может быть применим к данной ситуации.
ME>--
ME>Maxim Yegorushkin
Re[3]: Вывод аргументов шаблоной функции
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 01.06.05 14:55
Оценка: -1
Здравствуйте, Yacha, Вы писали:

I>>Это почему ты так решил? Здесь передается по значению, а значение копируется через ссылку, но это уже детали, не имеющие к foo отношения.


Y>Тип T должен выводиться на основании типа аргумента t, если я не прав, то поправте меня, в приведенном случае типом аргумента является
int &


Здесь компилятор может вывести две равноправных сигнатуры:

void foo(int);
void foo(int&);


И получить неоднозначно разрешаемую перегрузку.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Вывод аргументов шаблоной функции
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 01.06.05 14:55
Оценка:
Здравствуйте, MaximE, Вы писали:

>> Я понимаю, что правильным было бы
 template<typename T> void foo(T& t) { t = 1; }
, но

>> почему в первом случае T не может быть int& ?

ME>

ME>[temp.deduct.call] 14.8.2.1 Deducing template arguments from a function call


Не, тут конфликт круче получается. Конфликтуют правила дедукции аргументов шаблона и правила разрешения перегрузки.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[3]: Вывод аргументов шаблоной функции
От: Lorenzo_LAMAS  
Дата: 01.06.05 15:12
Оценка:
ГВ>Не, тут конфликт круче получается. Конфликтуют правила дедукции аргументов шаблона и правила разрешения перегрузки.

??????????????????
Of course, the code must be complete enough to compile and link.
Re[3]: Вывод аргументов шаблоной функции
От: Lorenzo_LAMAS  
Дата: 01.06.05 15:16
Оценка:
Тебе Максим ясно написал, процитировал стандарт — если есть ссылочный тип, то при выведении
параметра шаблона используется тип, на который ссылаются. ты можешь писать

template<class T>
void fun(T &){}

int main()
{
   int i = 0;
   int &ri = i;
   fun(ri);
}

и у тебя это компилится, а следуя твоей логике должна быть ссылка на ссылку?
Of course, the code must be complete enough to compile and link.
Re: Вывод аргументов шаблоной функции
От: Павел Кузнецов  
Дата: 01.06.05 17:25
Оценка:
Yacha,

>
> template<typename T>
> void foo(T t)
> {
>    t = 1;
> }
>
> ...
>
> int i = 0;
> int &ii = i;
> foo(ii);//здесь передается по значению, а хотелось бы по ссылке
>


Это из-за того, что в языке нет понятия выражений "ссылочного типа", соответственно, и выведен такой тип быть не может. Подробнее см. http://rsdn.ru/Forum/Message.aspx?mid=602565&amp;only=1
Автор: Павел Кузнецов
Дата: 12.04.04
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Вывод аргументов шаблоной функции
От: Павел Кузнецов  
Дата: 01.06.05 17:28
Оценка: 22 (1)
P.S.

> Это из-за того, что в языке нет понятия выражений "ссылочного типа", соответственно, и выведен такой тип быть не может. Подробнее см. http://rsdn.ru/Forum/Message.aspx?mid=602565&amp;only=1
Автор: Павел Кузнецов
Дата: 12.04.04


Кстати, полезное следствие такого свойства языка:
int& i = 10;
throw i;

Будет выброшено значение типа int, а не int&. http://rsdn.ru/Forum/Message.aspx?mid=368696&amp;only=1
Автор: Павел Кузнецов
Дата: 29.08.03
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Вывод аргументов шаблоной функции
От: Yacha Россия  
Дата: 02.06.05 05:46
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Yacha,


>>
>> template<typename T>
>> void foo(T t)
>> {
>>    t = 1;
>> }
>>
>> ...
>>
>> int i = 0;
>> int &ii = i;
>> foo(ii);//здесь передается по значению, а хотелось бы по ссылке
>>


ПК>Это из-за того, что в языке нет понятия выражений "ссылочного типа", соответственно, и выведен такой тип быть не может. Подробнее см. http://rsdn.ru/Forum/Message.aspx?mid=602565&amp;only=1
Автор: Павел Кузнецов
Дата: 12.04.04


Спасибо за ответ.
Re: Вывод аргументов шаблоной функции
От: Кодт Россия  
Дата: 02.06.05 15:18
Оценка:
Здравствуйте, Yacha, Вы писали:

<>
Если тебе нужно в функцию foo передать не копию, а именно ссылку (не потерять связь с оригинальным объектом — и чтобы foo его могла поменять) — то передавай обёртку.
#include <cassert>

// обёртка
template<class T>
struct ref_t // это не то же самое, что boost::ref !
{
  T* var;
  ref_t(T& v) : var(&v) {}

  operator T&() { return *var; }
  T& operator=(const T& value) { *var = value; return *this; }
  // ну и другие операторы...
};
// порождающая функция
template<class T> ref_t<T> ref(T& v) { return ref_t<T>(v); }



template<class T> void foo(T t) { t = 0; }


int main()
{
  int  x = 1;  foo(x);  assert(x==1);
  int& y = x;  foo(y);  assert(x==1); // это был всего лишь синоним для x
  int* z = &x; foo(*z); assert(x==1);

  foo(ref(x)); assert(x==0);

  return 0;
}
Перекуём баги на фичи!
Re[3]: Вывод аргументов шаблоной функции
От: Bell Россия  
Дата: 03.06.05 08:37
Оценка: +1
Здравствуйте, Павел Кузнецов, Вы писали:

Вкралась ошибочка:

ПК>Кстати, полезное следствие такого свойства языка:

ПК>
ПК>const int& i = 10;
ПК>throw i;
ПК>

ПК>Будет выброшено значение типа int, а не int&. http://rsdn.ru/Forum/Message.aspx?mid=368696&amp;only=1
Автор: Павел Кузнецов
Дата: 29.08.03
Любите книгу — источник знаний (с) М.Горький
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.