Frage

Ein Freund und ich diskutierten über C++-Vorlagen.Er fragte mich, was das bewirken soll:

#include <iostream>

template <bool>
struct A {
    A(bool) { std::cout << "bool\n"; }
    A(void*) { std::cout << "void*\n"; }
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new A< b > (c) > (d);
}

Die letzte Zeile in main enthält zwei sinnvolle Parses.Ist 'b' das Vorlagenargument oder ist b > (c) das Vorlagenargument?

Obwohl es trivial ist, dies zu kompilieren und zu sehen, was wir bekommen, haben wir uns gefragt, was die Mehrdeutigkeit löst?

War es hilfreich?

Lösung

AFAIK würde es so kompiliert werden new A<b>(c) > d.Dies ist meiner Meinung nach die einzig vernünftige Möglichkeit, es zu analysieren.Wenn der Parser unter normalen Umständen nicht davon ausgehen kann, dass ein Vorlagenargument > endet, würde dies zu viel mehr Mehrdeutigkeit führen.Wenn Sie es anders wollen, hätten Sie schreiben sollen:

new A<(b > c)>(d);

Andere Tipps

Wie von Leon & Lee angegeben, definiert 14.2/3 (C++ '03) dieses Verhalten explizit.

C++ '0x macht noch mehr Spaß, da für C++ eine ähnliche Regel gilt >>.Das Grundkonzept besteht darin, dass beim Parsen einer Template-Argument-Liste eine nicht verschachtelte >> werden als zwei verschiedene behandelt > > Token und nicht der richtige Shift-Operator:

template <bool>
struct A {
  A(bool);
  A(void*);
};

template <typename T>
class C
{
public:
  C (int);
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new C <A< b  >>  (c) > (d); // #1
    new C <A< b > >  (c) > (d); // #2
}

„#1“ und „#2“ sind oben gleichwertig.

Dies behebt natürlich das Ärgernis, Leerzeichen in verschachtelten Spezialisierungen hinzufügen zu müssen:

C<A<false>> c;  // Parse error in C++ '98, '03 due to "right shift operator"

Der C++-Standard definiert, dass if für einen Vorlagennamen gefolgt von einem <, Die < ist immer der Anfang der Vorlagenargumentliste und das erste nicht verschachtelte Argument > wird als Ende der Vorlagenargumentliste verwendet.

Wenn Sie beabsichtigt haben, dass das Ergebnis der > Wenn der Operator das Vorlagenargument ist, müssen Sie den Ausdruck in Klammern setzen.Sie benötigen keine Klammern, wenn das Argument Teil von a war static_cast<> oder ein anderer Vorlagenausdruck.

Die Gier des Lexers ist wahrscheinlich der entscheidende Faktor für das Fehlen von Klammern, um es explizit zu machen.Ich würde vermuten, dass der Lexer nicht gierig ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top