„auto” jako symbol zastępczy argumentu szablonu dla parametru funkcji

22

C ++ 20 pozwala na użycie autotypu parametru funkcji.

Czy pozwala również na użycie autojako symbolu zastępczego argumentu szablonu (nie podobnego, ale w duchu szablonu C ++ 17 <auto> w pewien sposób) dla typu parametru funkcji?

Tak więc następujący kod sprzed C ++ 20:

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

Można zapisać jako:

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

To nie kompiluje i działa ładnie z eksperymentalnej realizacji GCC dla pojęć.

Czy jest to poprawna składnia w C ++ 20?

Amir Kirsh
źródło
Z tego, co słyszałem, nieograniczone auto bezpośrednio przekłada się na szablony typename XYZ, co zdecydowanie sugeruje, że jest to uzasadniona składnia. Schludny .
Fureeish
2
Zauważ, że Clang się nie zgadza, a Clang i GCC mają ten sam spór co do tego, czy autojest dozwolone w [](const std::pair<auto, auto>& p){}(czy z -std=c++2alub -std=c++17).
orzech
Dziękuję @DavisHerring - Naprawiłem sformułowanie
Amir Kirsh

Odpowiedzi:

17

Ta składnia jest poprawna w specyfikacji technicznej pojęć C ++, ale nie w C ++ 20. W koncepcjach C ++ 20 autojest dozwolony tylko na najwyższym poziomie w typie parametru funkcji. Właściwą zasadą jest [dcl.spec.auto] ust. 2 :

Zastępczy typu-specyfikator w postaci typu ograniczenie [opt] automogą być stosowane jako dekl-specyfikacją z dekl-specyfikatora-seq o parametrze-zgłoszenia zgłoszenia funkcyjnym lub lambda ekspresji i, jeśli to nie jest auto specyfikator typu wprowadzający typ trailing-return (patrz poniżej), jest symbolem zastępczym typu ogólnego parametru deklaracji funkcji lub wyrażenia lambda. [Uwaga: Posiadanie symbolu zastępczego typu parametru ogólnego oznacza, że ​​funkcja jest skróconym szablonem funkcji (9.3.3.5 [dcl.fct]) lub lambda jest ogólną lambda (7.5.5 [wyśw. Prim.]). —Wskazówka]

(Jeśli sprawdzisz sformułowania w najnowszym roboczym szkicu w momencie pisania, znajdziesz nieco inną zasadę. Powyższa zasada została zmodyfikowana przez główny numer 2447 , który został głosowany w ostatecznym projekcie C ++ 20 w Pradze posiedzenie komitetu tydzień temu.)

Specyfikator deklinacji w parametrze funkcji jest początkową sekwencją słów kluczowych i nazw typów na początku deklaracji parametru. Powyższa reguła pozwala autona najwyższym poziomie:

void f(auto x);

... ale tylko jako specyfikator deklaracji . autonie jest dozwolone, gdy jest zagnieżdżone w specyfikatorze decl :

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

... i jest również niedozwolony gdzie indziej w typie parametru:

void f(void (*p)(auto));
Richard Smith
źródło
Wow, nie wiedziałem tego! Link CWG daje obecnie 404, więc czy możesz krótko wyjaśnić uzasadnienie tego ograniczenia?
LF
To jest całkowicie rozczarowujące.
Fureeish
1
Przepraszamy, problem CWG i jego zmiana brzmienia nie są jeszcze publicznie widoczne. Ta reguła została wprowadzona przez open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html, a intencja / uzasadnienie miało być zgodne z tym, co już zezwoliliśmy na ogólne lambdas.
Richard Smith
4
@LF: Problem CWG i tak nie jest tak naprawdę istotny: poprawił błąd w słowie, który sugerował, że pewne zastosowania autokońcowego typu zwrotu liczone są jako tego rodzaju autoużycie.
Davis Herring