'auto' як заповнення аргументу шаблону для параметра функції


22

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

Чи дозволяє це також використовувати autoяк заповнювач аргументу шаблону (не схожий, але в дусі шаблону <a +> шаблону 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;
}

Він компілює і працює чудово з експериментальною реалізацією ССЗ для концепцій.

Це законний синтаксис із C ++ 20?


З того, що я чув, необмеженість auto безпосередньо перекладається на шаблонізовану typename XYZ, що сильно означає, що це законний синтаксис. Акуратний .
Fureeish

2
Зверніть увагу , що Clang не згоден з цим і що Clang і GCC мають однакове незгоду про те , autoдопускається в [](const std::pair<auto, auto>& p){}(будь то з -std=c++2aабо -std=c++17).
волоський горіх


Дякую @DavisHerring - Я виправив формулювання
Амір Кірш,

Відповіді:


17

Цей синтаксис є дійсним у Технічній специфікації понять C ++, але не в C ++ 20. У поняттях C ++ 20 autoдозволено лише на верхньому рівні в типі функціонального параметра. Відповідне правило - пункт [dcl.spec.auto] :

Заповнювач типу Специфікатор вид типу-обмеження [відмову] autoможе бути використаний в якості Децла-специфікатор в Децла-специфікаторами-SEQ про наявність параметра-декларації в оголошенні функції або лямбда-виразі , і, якщо це не auto специфікатор типу, що вводить тип зворотного повернення (див. нижче), є загальним параметром заповнення типу декларації функції або лямбда-виразу . [Примітка: наявність загального параметра типу заповнювача означає, що функція є скороченим шаблоном функції (9.3.3.5 [dcl.fct]) або лямбда - це загальна лямбда (7.5.5 [expr.prim.lambda]). —Закінчити примітку]

(Якщо ви перевірите формулювання в останньому робочому проекті під час написання, ви знайдете дещо інше правило. Вищевказане правило було змінено основним питанням 2447 , яке було проголосовано в остаточному проекті С ++ 20 у Празі засідання комітету тиждень тому.)

Специфікатор decl у параметрі функції - це початкова послідовність ключових слів та імен типів на початку декларації параметра. Наведене вище правило дозволяє autoна найвищому рівні:

void f(auto x);

... але лише як специфікатор decl . autoзаборонено, якщо вкладено в специфікатор decl :

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

... і також не дозволено в іншому місці типу параметра:

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

Нічого собі, я цього не знав! Зараз посилання CWG дає 404, тож чи можете ви коротко пояснити обґрунтування цього обмеження?
LF

Це вкрай невтішно.
Fureeish

1
На жаль, проблема CWG та її зміна формулювань поки не доступні для всіх. Правило в питанні був введений open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html і мета / обгрунтування повинно було бути відповідає тому , що ми вже дозволили родовими лямбда.
Річард Сміт

4
@LF: Проблема CWG так чи інакше не актуальна: вона виправила формулювальну помилку, яка передбачала, що певні способи використання autoтипу зворотного повернення зараховуються як такий тип autoвикористання.
Оселедець Девіса
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.