Ссылка на l-значение удержания шаблона функции и универсальная ссылка

Допустим, у меня есть функция copy:

template <typename Buf>
void copy(
    Buf&& input_buffer,
    Buf& output_buffer) 
{}

В котором input_buffer является универсальной ссылкой и output_buffer является ссылкой на значение l.

Reference collapsing rules удостовериться input_buffer действительно, независимо от выводимого типа BufУниверсальный справочник и output_buffer действительно ссылка на l-значение.

Тем не менее, мне интересно, как тип Buf выводится здесь.

я узнал что copy передается значение r как input_buffer, (и значение l как output_bufferочевидно) Buf это не ссылочный тип.

Однако, если я передам два l-значения, программа не скомпилируется:

int i = 4;
int j = 6;

_copy(i, j);

Я бы ожидал, что компилятор выведет Buf в int&, Следуя правилам свертывания ссылок, я бы ожидал input_buffer стать ссылкой на l-значение, то есть & + && -> &, а также output_buffer стать ссылкой на l-значение тоже; & + & -> &,

Итак, вопрос: почему этот код не компилируется?

(Примечание: я не обязательно прошу решение проблемы, но объяснение.)

Если мне нужно уточнить, не стесняйтесь спрашивать.

РЕДАКТИРОВАТЬ: если позвоните: copy(i, j);Компилятор GNU GCC выдает: error: нет соответствующей функции для вызова функции "copy(int&, int&)" note:андидат: шаблон void copy(Buf&&, buf&) note: сбой вывода / замены аргумента шаблона: note: выведены конфликтующие типы для параметра 'Buf' ('int&'и'int')

если позвоните: copy<int&>(i, j);ХОРОШО.

1 ответ

Решение

А) Тип вычета для пересылки ссылки:

template<class T>
void f(T&& val) {}

[a.1] когда вы передаете Lvalue T выводится T&, Так что у тебя есть

void f(T& && ){} -after reference collapsing-> void f(T&){}

[a.2] при прохождении Rvalue T выводится T, Так что у тебя есть

void f(T&& ) {}

б) Тип вычета для справки, кроме пересылки справки:

template<class T>
void f(T& param){}

когда вы передадите Lvalue, T выводится T, param имеет тип T& но аргумент шаблона Tне T&,

Так что ниже код компилируется

int i = 10;
copy(20,i);

потому что вывод типа для первого аргумента возвращает Buf==int с тех пор как вы прошли 20 Rvalue. И результат удержания для второго аргумента также возвращает Buf==int, Так что в обоих случаях Buf то же самое, код компилируется.

Код, который не компилируется:

int i=1;
int j=2;
copy(i,j);

Что такое выводимый тип для первого аргумента? Вы передаете L-значение, так Buf является int&, Второй вычет возвращается Buf==int, Эти два выведенных типа не совпадают, поэтому код не компилируется.

Другие вопросы по тегам