Einige fantastische moderne C ++ - Funktionen, die jeder Entwickler kennen sollte

Als Sprache hat sich C ++ stark weiterentwickelt.

Natürlich geschah dies nicht über Nacht. Es gab eine Zeit, in der C ++ keine Dynamik aufwies. Es war schwierig, die Sprache zu mögen.

Die Dinge änderten sich jedoch, als das C ++ - Standardkomitee beschloss, das Rad zu drehen.

Seit 2011 hat sich C ++ zu einer dynamischen und sich ständig weiterentwickelnden Sprache entwickelt, auf die viele Menschen gehofft haben.

Verstehen Sie nicht die falsche Vorstellung, dass die Sprache einfacher geworden ist. Es ist immer noch eine der schwierigsten Programmiersprachen, wenn nicht die schwierigste, die weit verbreitet sind. C ++ ist aber auch viel benutzerfreundlicher geworden als seine Vorgängerversionen.

In meinem letzten Beitrag habe ich über die C ++ - Algorithmusbibliothek gesprochen, die in den letzten Jahren erweitert wurde.

Heute werden wir uns einige neue Funktionen ansehen (ab C ++ 11, das übrigens bereits 8 Jahre alt ist), die jeder Entwickler gerne wissen würde.

Beachten Sie auch, dass ich einige erweiterte Funktionen in diesem Artikel übersprungen habe, aber ich bin bereit, in Zukunft darüber zu schreiben. ? ️

Gehen!

Das Auto-Schlüsselwort

Als C ++ 11 zum ersten Mal eingeführt wurde auto, wurde das Leben einfacher.

Die Idee von autowar, den C ++ - Compiler dazu zu bringen, den Typ Ihrer Daten beim Kompilieren abzuleiten - anstatt Sie zu veranlassen, den Typ jedes Mal zu deklarieren . Das war so praktisch, wenn Sie Datentypen wie nt, int >>> haben?map

Original text


Schauen Sie sich die Zeilennummer 5 an initializer. Ohne eine können Sie nichts deklarieren . Das macht eigentlich Sinn. Zeile 5 teilt dem Compiler nicht mit, welcher Datentyp sein kann.

Anfangs autowar etwas begrenzt. Dann wurde in den späteren Versionen der Sprache mehr Leistung hinzugefügt!

In den Zeilen 7 und 8 habe ich die Initialisierung in Klammern verwendet. Dies war auch eine neue Funktion, die in C ++ 11 hinzugefügt wurde.

Denken Sie daran, autodass der Compiler bei Verwendung eine Möglichkeit haben muss, Ihren Typ abzuleiten.

Nun eine sehr schöne Frage, was passiert, wenn wir schreibenauto a = {1, 2, 3} ? Ist das ein Kompilierungsfehler? Ist das ein Vektor?

Tatsächlich hat C ++ 11 pe> eingeführt. Die in Klammern gesetzte initialisierte Liste wird als dieser leichte Container betrachtet, wenn die automatische Entscheidung getroffen wird.std::initializer_listlare

Wie bereits erwähnt, kann die Typableitung durch den Compiler bei komplexen Datenstrukturen sehr nützlich sein:

Vergessen Sie nicht, Zeile 25 zu lesen! Der Ausdruck auto [v1,v2] = itr.secondist buchstäblich eine neue Funktion in C ++ 17. Dies wird als strukturierte Bindung bezeichnet . In früheren Versionen der Sprache mussten Sie jede Variable separat extrahieren. Die strukturierte Bindung hat es jedoch viel bequemer gemacht.

Wenn Sie die Daten mithilfe einer Referenz abrufen möchten, fügen Sie einfach ein Symbol hinzu - auto &[v1,v2] = itr.second.

Ordentlich.

Der Lambda-Ausdruck

In C ++ 11 wurden Lambda-Ausdrücke eingeführt, ähnlich wie anonyme Funktionen in JavaScript. Sie sind Funktionsobjekte ohne Namen und erfassen Variablen in verschiedenen Bereichen, basierend auf einer präzisen Syntax. Sie können auch Variablen zugewiesen werden.

Lambdas sind sehr nützlich, wenn Sie eine kleine schnelle Aufgabe in Ihrem Code benötigen, aber nicht bereit sind, eine separate Funktion dafür zu schreiben. Eine andere ziemlich häufige Verwendung besteht darin, sie als Vergleichsfunktionen zu verwenden.

Das obige Beispiel hat viel zu sagen.

Beachten Sie zunächst, wie die Initialisierung mit geschweiften Klammern das Gewicht für Sie erhöht. Dann kommt generisch begin(), end(), das auch eine Ergänzung in C ++ 11 ist. Dann kommt die Lambda-Funktion als Komparator für Ihre Daten. Die Parameter der Lambda-Funktion werden deklariertautowelches in C ++ 14 hinzugefügt wurde. Vorher konnten wir keine autoFunktionsparameter verwenden.

Beachten Sie, wie wir den Lambda-Ausdruck mit einer eckigen Klammer beginnen []. Sie definieren den Umfang des Lambda - wie viel Autorität es über die lokalen Variablen und Objekte hat.

Wie in diesem fantastischen Repository unter modernem C ++ definiert:

  • [] - erfasst nichts. Sie können also keine lokale Variable des äußeren Bereichs in Ihrem Lambda-Ausdruck verwenden. Sie können nur die Parameter verwenden.
  • [=]- Erfasst lokale Objekte (lokale Variablen, Parameter) im Bereich nach Wert. Sie können sie verwenden, aber nicht ändern.
  • [&] - Erfassen lokaler Objekte (lokale Variablen, Parameter) im Bereich als Referenz. Sie können sie ändern. Wie das folgende Beispiel.
  • [this]- thisZeiger nach Wert erfassen .
  • [a, &b]- Objekte anach Wert und bReferenz erfassen .

Wenn Sie also innerhalb Ihrer Lambda-Funktion Ihre Daten in ein anderes Format umwandeln möchten, können Sie Lambda verwenden, indem Sie den Umfang nutzen. Zum Beispiel:

Wenn Sie im obigen Beispiel lokale Variablen mit value ( [factor]) in Ihrem Lambda-Ausdruck erfasst haben , können Sie dies factorin Zeile 5 nicht ändern. Sie haben einfach kein Recht dazu. Missbrauche deine Rechte nicht! ?

Beachten Sie schließlich, dass wir valals Referenz nehmen. Dies stellt sicher, dass jede Änderung innerhalb der Lambda-Funktion tatsächlich die ändert vector.

Init-Anweisungen in if & switch

Diese Funktion von C ++ 17 hat mir sofort sehr gut gefallen, nachdem ich davon erfahren hatte.

Anscheinend können Sie jetzt Variablen initialisieren und die Bedingung dafür überprüfen - gleichzeitig innerhalb des if/switchBlocks. Dies ist sehr hilfreich, um Ihren Code präzise und sauber zu halten. Die allgemeine Form ist:

if( init-statement(x); condition(x)) { // do some stuff here } else { // else has the scope of x // do some other stuff }

Tun Sie es in der Kompilierungszeit von constexpr

constexpr ist cool!

Angenommen, Sie müssen einen Ausdruck auswerten, und sein Wert ändert sich nach der Initialisierung nicht. Sie können den Wert vorberechnen und dann als Makro verwenden. Oder wie C ++ 11 angeboten, können Sie verwenden constexpr.

Programmierer neigen dazu, die Laufzeit ihrer Programme so weit wie möglich zu reduzieren. Wenn es also einige Vorgänge gibt, die der Compiler ausführen und die Laufzeit entlasten kann, kann die Laufzeit verbessert werden.

Der obige Code ist ein sehr verbreitetes Beispiel für constexpr.

Da wir die Fibonacci-Berechnungsfunktion als deklariert haben constexpr, kann der Compiler vorberechnenfib(20)in der Kompilierungszeit. Nach dem Kompilieren kann es die Zeile ersetzen

const long long bigval = fib(20);mit

const long long bigval = 2432902008176640000;

Beachten Sie, dass das übergebene Argument ein constWert ist. Dies ist ein wichtiger Punkt der deklarierten Funktionen constexpr- die übergebenen Argumente sollten auch constexproder sein const. Andernfalls verhält sich die Funktion wie eine normale Funktion, was bedeutet, dass während der Kompilierungszeit keine Vorberechnung erfolgt.

Variablen können auch sein constexpr. In diesem Fall müssen diese Variablen, wie Sie sich vorstellen können, in der Kompilierungszeit auswertbar sein. Andernfalls wird ein Kompilierungsfehler angezeigt.

Interessanterweise später in C ++ 17 constexpr-ifundconstexpr-lambdawurden vorgestellt.

Tupel

Ähnlich wie pair, tupleist eine Sammlung von fester Größe Werten verschiedenen Datentypen.

Manchmal ist es bequemer zu verwenden std::arrayals tuple. arrayähnelt einem einfachen Array vom Typ C zusammen mit einigen Funktionen der C ++ - Standardbibliothek. Diese Datenstruktur wurde in C ++ 11 hinzugefügt.

Abzug von Klassenvorlagenargumenten

Ein sehr ausführlicher Name für ein Feature. Die Idee ist, dass ab C ++ 17 die Argumentableitung für Vorlagen auch für Standardklassenvorlagen erfolgt. Bisher wurde es nur für Funktionsvorlagen unterstützt.

Als Ergebnis,

std::pair user = {"M", 25}; // previous std::pair user = {"M", 25}; // C++17

Die Art des Abzugs erfolgt implizit. Dies wird noch bequemer für tuple.

// previous std::tuple user ("M", "Chy", 25); // deduction in action! std::tuple user2("M", "Chy", 25);

Diese Funktion macht keinen Sinn, wenn Sie mit C ++ - Vorlagen nicht ganz vertraut sind.

Intelligente Zeiger

Zeiger können höllisch sein.

Aufgrund der Freiheit, die Sprachen wie C ++ Programmierern bieten, wird es manchmal sehr einfach, sich in den Fuß zu schießen. In vielen Fällen sind Zeiger für den Schaden verantwortlich.

Glücklicherweise hat C ++ 11 intelligente Zeiger eingeführt, Zeiger, die weitaus praktischer sind als Rohzeiger. Sie helfen Programmierern, Speicherlecks zu verhindern, indem sie sie nach Möglichkeit freigeben. Sie bieten auch Ausnahmesicherheit.

Ich dachte daran, in diesem Beitrag über die intelligenten Zeiger in C ++ zu schreiben. Aber anscheinend gibt es viele wichtige Details über sie. Sie verdienen ihren eigenen Beitrag und ich bin sicherlich bereit, in naher Zukunft einen über sie zu schreiben.

Das ist alles für heute. Denken Sie daran, dass C ++ in den neuesten Versionen der Sprache tatsächlich viel mehr neuere Funktionen hinzugefügt hat. Sie sollten sie überprüfen, wenn Sie interessiert sind. Hier ist ein fantastisches Repository für modernes C ++, das buchstäblich Awesome Modern C ++ heißt!

Adios!