'auto' как заполнитель аргумента шаблона для параметра функции - PullRequest
22 голосов
/ 23 февраля 2020

C ++ 20 позволяет использовать auto для типа параметра функции.

Позволяет ли также использовать auto в качестве заполнителя аргумента шаблона (не похоже, но в духе C +) +17 шаблон в некотором смысле) для типа параметра функции?

Таким образом, следующий код, предварительно C ++ 20:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

Может быть записан как:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

Он компилируется и прекрасно работает с экспериментальной реализацией G CC для концепций.

Это допустимый синтаксис в C ++ 20?

1 Ответ

17 голосов
/ 23 февраля 2020

Этот синтаксис действителен в Технической спецификации концепций C ++, но не в C ++ 20. В концепциях C ++ 20 auto разрешено только на верхнем уровне в типе параметра функции. Соответствующее правило: [dcl.spe c .auto], пункт 2 :

A указатель типа заполнителя формы ограничение типа [opt] auto может использоваться как decl-спецификатор из decl-спецификатор-seq объявления параметров объявления функции или лямбда-выражения и, если это не auto спецификатор типа , вводящий тип конечного возврата (см. ниже) , является generi c заполнителем типа параметра объявления функции или лямбда-выражением . [Примечание: Наличие заполнителя типа параметра c означает, что функция является сокращенным шаблоном функции (9.3.3.5 [dcl.fct]) или лямбда является обобщенной лямбда c (7.5.5 [expr.prim. лямбда]). - конец примечания]

(Если вы проверите формулировку в самом последнем рабочем проекте на момент написания, вы найдете несколько иное правило. Вышеупомянутое правило было изменено из-за основной проблемы 2447 , который был проголосован за окончательный проект C ++ 20 на заседании Пражского комитета через неделю go.)

decl-спецификатор s в параметре функции являются начальной последовательностью ключевых слов и имен типов в начале объявления параметров. Приведенное выше правило разрешает auto на верхнем уровне:

void f(auto x);

... но только как decl-спецификатор . auto не допускается, если вложено в decl-спецификатор :

void f(std::vector<auto> x);

... и также не разрешено в других местах в параметре типа:

void f(void (*p)(auto));
...