Frage

Ich bin ein wenig neugierig auf einige der neuen Features von C ++ 0x. Insbesondere bereichsbasierte for-Schleifen und < strong> initializer Listen . Beide Funktionen erfordern eine benutzerdefinierte Klasse, um richtig funktionieren zu können.

Ich kam accross diesen Beitrag und während die Top-Antwort war hilfreich. Ich weiß nicht, ob es ganz richtig ist (Ich bin wahrscheinlich nur völlig Missverständnis, siehe 3. Kommentar auf erste Antwort) . Nach den aktuellen Spezifikationen initializer Listen definieren die Header einen Typen:

template<class E> class initializer_list {
public:
    initializer_list();

    size_t size() const; // number of elements
    const E* begin() const; // first element
    const E* end() const; // one past the last element
};

Sie können dies in den technischen Daten sehen, nur Strg + F 'Klasse initializer_list' .

Damit = {1,2,3} implizit in die initializer_list Klasse gegossen werden kann, muss der Compiler einige Kenntnisse über die Beziehung zwischen {} und initializer_list haben. Es gibt keinen Konstruktor, der alles erhält, so dass die initializer_list soweit ich sagen kann, ist ein Wrapper, der auf alles, was der Compiler gebunden wird tatsächlich erzeugt wird.

Es ist das gleiche mit dem for( : ) Schleife, die auch einen benutzerdefinierten Typ (obwohl nach den Spezifikationen zu arbeiten erfordert, aktualisiert keinen Code für Arrays und initializer Listen benötigen. Aber initializer Listen erfordern <initializer_list>, so dass es ein Benutzer -defined Code Anforderung durch einen Bevollmächtigten).

Bin ich Missverständnis vollständig, wie das hier funktioniert? Ich bin nicht falsch in der Annahme, dass diese neuen Funktionen infact Verlassen Sie sich extrem stark auf Benutzercode. Es fühlt sich an, als ob die Merkmale unausgegoren sind, und statt die gesamte Funktion in den Compiler bauen, wird es durch den Compiler Halb getan und halb fertig in einschließt. Was ist der Grund dafür?

Edit: Ich tippte 'verlassen sich stark auf Compiler Code', und nicht 'verlassen sich stark auf Anwendercode'. Das finde ich warf völlig meine Frage ab. Meine Verwirrung geht es nicht um neue Features in den Compiler gebaut, es ist Dinge, die in den Compiler erstellt werden, die auf Benutzercode verlassen.

War es hilfreich?

Lösung

  

Ich bin nicht falsch in der Annahme, dass diese neuen Funktionen haben extrem stark auf Compiler Code infact verlassen

Sie verlassen sich sehr auf den Compiler. Egal, ob Sie eine Kopf- oder nicht enthalten müssen, ist die Tatsache, dass in beiden Fällen würde die Syntax ein Parsing-Fehler mit heute Compiler sein. Die for (:) passt nicht ganz in die heute Standard, wo die einzige erlaubte Konstrukt for(;;)

  

Es fühlt sich an, als ob die Merkmale unausgegoren sind, und statt die gesamte Funktion in den Compiler bauen, wird es durch den Compiler Halb getan und halb fertig in einschließt. Was ist der Grund dafür?

Die Unterstützung muss im Compiler implementiert werden, aber Sie müssen ein System Header enthalten, dafür zu arbeiten. Dies kann ein paar Zwecke, im Fall der Initialisierung Listen dient, bringt es die Art (Schnittstelle zur Compiler-Unterstützung) in dem Gültigkeitsbereich für den Benutzer, so dass Sie einen Weg, es zu benutzen haben können (man denkt wie va_args in C ist). Im Fall des Bereichs basierte für (die nur syntaktischen Zucker) Sie Bereich in Umfang mitbringen müssen, damit der Compiler es ist Magie durchführen kann. Beachten Sie, dass die Standard-for ( for-range-declaration : expression ) statement als äquivalent zu ([6.5.4] / 1 im Entwurf) definiert:

{ 
   auto && __range = ( expression ); 
   for ( auto __begin = std::Range<_RangeT>::begin(__range), 
         __end = std::Range<_RangeT>::end(__range); 
         __begin != __end; 
         ++__begin ) { 
      for-range-declaration = *__begin; 
      statement 
   } 
} 

Wenn Sie es verwenden mögen nur auf Arrays und STL-Containern, die ohne das Range Konzept umgesetzt werden könnten (nicht im C ++ 0x Sinne), aber wenn Sie die Syntax in benutzerdefinierten Klassen erweitern (eigene Container der Compiler) kann auf die bestehende Range Vorlage (mit Ihrer eigenen möglichen Spezialisierung leicht abhängen). Der Mechanismus, der in Abhängigkeit von einer Vorlage definiert wird, ist äquivalent eine statische Schnittstelle auf den Behälter erforderlich ist.

Die meisten anderen Sprachen haben in Richtung gegangen, um eine regelmäßige Schnittstelle zu erfordern (sagen Container, ...) und mit Laufzeit-Polymorphismus, dass auf. Wenn das in C ++, die ganze STL getan werden sollte, würde durch eine große Refactoring gehen als STL-Container keine gemeinsame Basis oder Schnittstelle teilen, und sie sind nicht bereit, polimorphically verwendet werden.

Wenn überhaupt, wird der aktuelle Standard nicht underbaked durch die Zeit, es geht aus.

Andere Tipps

Es ist nur Syntax Zucker. Der Compiler wird die gegebenen syntaktischen Konstrukte in äquivalente C ++ Ausdrücke erweitern, die die Standardtypen / Symbolnamen direkt verweisen.

Dies ist nicht die einzige starke Kopplung, die modernen C ++ Compiler zwischen ihrer Sprache und der „Außenwelt“ haben. Zum Beispiel ist extern "C" ein bisschen eine Sprache Hack C des Verbindungsmodells aufzunehmen. Sprache orientierte Wege zu erklären faden lokalen Speicher hängen implizit auf eine Menge RTL hackery an die Arbeit.

Oder sehen Sie C. Wie greifen Sie Argumente über ... weitergegeben? Sie müssen sich auf die Standard-Bibliothek verlassen; aber das nutzt Magie, die eine sehr harte Abhängigkeit hat, wie genau der C-Compiler legt Stapelrahmen.

UPDATE:

Wenn überhaupt, der Ansatz C ++ hier genommen hat mehr im Sinne von C ++ als die Alternative ist - die einen Eigen Sammlung oder Range-Typen, gebacken hinzuzufügen in die Sprache sein würden. Stattdessen es wird durch einen vom Hersteller definierten Bereich Typ. Ich sehe nicht, es ist wirklich so viel anders variadische Argumente, die ohne die herstellerdefinierten ähnlich nutzlos sind Accessor-Makros.

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