Здравствуйте, 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& ?
Тут нет правильного или неправильного. Следует сделать так, как тебе нужно
Здравствуйте, 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.: Винодельческие провинции — это есть рулез!
Здравствуйте, 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>Тут нет правильного или неправильного. Следует сделать так, как тебе нужно
, но > почему в первом случае 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
Здравствуйте, 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.: Винодельческие провинции — это есть рулез!
Здравствуйте, 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.: Винодельческие провинции — это есть рулез!
Тебе Максим ясно написал, процитировал стандарт — если есть ссылочный тип, то при выведении
параметра шаблона используется тип, на который ссылаются. ты можешь писать
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.
> template<typename T>
> void foo(T t)
> {
> t = 1;
> }
>
> ...
>
> int i = 0;
> int &ii = i;
> foo(ii);//здесь передается по значению, а хотелось бы по ссылке
>
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Yacha,
>>
>> template<typename T>
>> void foo(T t)
>> {
>> t = 1;
>> }
>>
>> ...
>>
>> int i = 0;
>> int &ii = i;
>> foo(ii);//здесь передается по значению, а хотелось бы по ссылке
>>
<>
Если тебе нужно в функцию 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); // это был всего лишь синоним для xint* z = &x; foo(*z); assert(x==1);
foo(ref(x)); assert(x==0);
return 0;
}