Может ли ссылка на пересылку быть наложена псевдонимом шаблона?

Это продолжение моего предыдущего вопроса:

Может ли шаблон псевдонима идентификации быть ссылкой для пересылки?

Кажется, что следующий код работает как в Clang 3.7.0 ( демо), так и в GCC 6.0.0 ( демо):

template <class T>
using forwarding_reference = T&&;

template <class T>
void foo(forwarding_reference<T>) {}

int main()
{
  int i{};
  foo(i);
  foo(1);
}

Правильны ли компиляторы заменить шаблон псевдонима ссылкой для пересылки, и это может быть причудливым способом написания?

1 ответ

Решение

Это действительно соответствует стандарту. §14.5.7/2:

Когда идентификатор шаблона ссылается на специализацию шаблона псевдонима, он эквивалентен связанному типу, полученному путем подстановки его аргументов шаблона для параметров шаблона в идентификаторе типа шаблона псевдонима.

Теперь учтите, что при выводе аргумента шаблона проверяется только тип параметра (в терминах параметров шаблона) - §14.8.2.1/1:

Вывод аргумента шаблона выполняется путем сравнения каждого типа параметра шаблона функции (вызовите его P ) с типом соответствующего аргумента вызова (вызвать его A), как описано ниже.

Согласно первой цитате, тип параметра, т.е. forwarding_reference<T>, эквивалентно T&&, следовательно P является T&& и не может быть никакой разницы в отношении вычета.

Такой же вывод был сделан комитетом в отчете о дефекте относительно этого точного сценария № 1700:

Поскольку типы параметров функции одинаковы, независимо от того, были ли они записаны напрямую или через шаблон псевдонимов, вычет должен обрабатываться одинаково в обоих случаях.

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