'auto' als Platzhalter für Vorlagenargumente für einen Funktionsparameter

22

In C ++ 20 kann der autoFunktionsparametertyp verwendet werden.

Ermöglicht es auch die Verwendung autoeines Platzhalters als Vorlagenargument (nicht ähnlich, aber in gewisser Weise im Sinne der C ++ 17-Vorlage <auto> ) für den Funktionsparametertyp?

Also der folgende Code vor C ++ 20:

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

Könnte geschrieben werden als:

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

Es kompiliert und funktioniert gut mit der experimentellen GCC-Implementierung für Konzepte.

Ist es eine legitime Syntax mit C ++ 20?

Amir Kirsh
quelle
Nach dem , was ich gehört habe, bedeutet unbeschränkt auto direkt Templatisiert typename XYZ, was stark bedeuten würde, dass es sich um die legitime Syntax handelt. Ordentlich .
Fureeish
2
Beachten Sie, dass Clang nicht einverstanden ist und dass Clang und GCC die gleiche Meinungsverschiedenheit darüber haben, ob (ob mit oder ) autoerlaubt ist . [](const std::pair<auto, auto>& p){}-std=c++2a-std=c++17
Walnuss
Vielen @DavisHerring Sie - ich habe den Wortlaut festgelegt
Amir Kirsh

Antworten:

17

Diese Syntax ist in der technischen Spezifikation für C ++ - Konzepte gültig, jedoch nicht in C ++ 20. In C ++ 20-Konzepten autoist dies nur auf oberster Ebene in einem Funktionsparametertyp zulässig. Die relevante Regel ist [dcl.spec.auto] Absatz 2 :

Ein Platzhalter-Typ-Spezifizierer von der Form Typ-constraint [opt] autokann eingesetzt werden DECL-Spezifizierer des DECL-Spezifizierer-seq eines Parameter Deklaration einer Funktionsdeklaration oder lambda-Ausdruck und, wenn es nicht das ist , auto Der Typspezifizierer, der einen Trailing-Return-Typ einführt (siehe unten), ist ein generischer Platzhalter für den Parametertyp der Funktionsdeklaration oder des Lambda-Ausdrucks. [Hinweis: Ein Platzhalter für einen generischen Parametertyp bedeutet, dass die Funktion eine abgekürzte Funktionsvorlage (9.3.3.5 [dcl.fct]) oder das Lambda ein generisches Lambda (7.5.5 [expr.prim.lambda]) ist. - Endnote]

(Wenn Sie den Wortlaut des letzten Arbeitsentwurfs zum Zeitpunkt des Schreibens überprüfen, werden Sie eine etwas andere Regel finden. Die obige Regel wurde durch die Kernausgabe 2447 geändert , die in den endgültigen Entwurf von C ++ 20 in Prag aufgenommen wurde Ausschusssitzung vor einer Woche.)

Die Deklarationsspezifizierer in einem Funktionsparameter sind die anfängliche Folge von Schlüsselwörtern und Typnamen zu Beginn der Parameterdeklaration. Die obige Regel erlaubt autodort auf oberster Ebene:

void f(auto x);

... aber nur als Deklarationsspezifizierer . autoist nicht zulässig, wenn es in einem Deklarationsspezifizierer verschachtelt ist :

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

... und ist auch an anderer Stelle im Parametertyp nicht zulässig:

void f(void (*p)(auto));
Richard Smith
quelle
Wow, das wusste ich nicht! Der CWG-Link gibt derzeit 404 an. Können Sie die Gründe für diese Einschränkung kurz erläutern?
LF
Das ist äußerst enttäuschend.
Fureeish
1
Entschuldigung, das CWG-Problem und seine Wortlautänderung sind noch nicht öffentlich sichtbar. Die fragliche Regel wurde von open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html eingeführt, und die Absicht / Begründung sollte mit dem übereinstimmen, was wir bereits für generische Lambdas zugelassen haben.
Richard Smith
4
@LF: Das CWG-Problem ist sowieso nicht wirklich relevant: Es hat einen Wortlautfehler korrigiert, der implizierte, dass bestimmte Verwendungen autofür einen nachfolgenden Rückgabetyp als diese Art der autoVerwendung gezählt wurden.
Davis Herring