C++23 : Une bibliothèque standard modularisée et deux nouvelles fonctions

C++23 : Une bibliothèque standard modularisée et deux nouvelles fonctions

2023-08-22 16:13:00

La bibliothèque standard C++23 brille par des améliorations impressionnantes. Dans cet article, je parlerai de la bibliothèque standard modularisée et des deux fonctionnalités pratiques std::print et std::println écrire.

Publicité




Rainer Grimm travaille depuis de nombreuses années en tant qu’architecte logiciel, chef d’équipe et responsable de la formation. Il aime écrire des articles sur les langages de programmation C++, Python et Haskell, mais aime aussi intervenir fréquemment lors de conférences spécialisées. Sur son blog Modernes C++, il parle intensément de sa passion pour le C++.

Chaque défi de programmation dans un nouveau langage commence par le programme “Hello World”. Depuis C++98, ceci a été notre point de départ :

#include 

int main() {

    std::cout << "Hello Worldn"; 

}

Franchement, vous devez abandonner vos vieilles habitudes en C++23. Le programme « Hello World » ressemble désormais à ceci :

import std;

int main() {

    std::println("Hello World"); 

}

Laissez-moi analyser le programme.

Publicité

C++23 prend en charge une bibliothèque standard modularisée. Avec la simple commande import std; toute la bibliothèque standard est à votre disposition. Si vous aimez aussi les fonctions C globales printf tu dois l'utiliser import std.compat; utiliser. Voici le programme "Hello World" correspondant avec printf:

import std.compat;

int main() {

    printf("Hello Worldn"); 

}

La bibliothèque standard modularisée apporte deux améliorations majeures : un temps de compilation et une convivialité considérablement améliorés.

L'import de la bibliothèque standard (import std) est littéralement « gratuit ». Cela signifie que les temps de compilation sont considérablement réduits. Les premiers chiffres tirés de l'expérience indiquent que les temps de compilation sont réduits d'un facteur d'au moins 10. La raison de cette amélioration est évidente. Au lieu d'inclure successivement vos fichiers d'en-tête, vous importez un module. Il n’existe donc qu’un seul module contenant toute la bibliothèque standard C++23. Jusqu'à présent, seul le compilateur MSVC prend en charge cette bibliothèque standard modularisée : Tutoriel : Importer la bibliothèque standard C++ à l'aide de modules depuis la ligne de commande.

Supposons que vous souhaitiez la fonction std::accumulate utiliser. Savez-vous quel fichier d'en-tête inclure ? Est-ce le fichier d'en-têtenumeric>,functional> oualgorithm>? C'était peut-être trop facile pour toi. Comment ça va maintenant ? std::forward ou pourquoi le programme suivant ne peut-il pas être compilé ?

int main() {

    auto list = {1, 2, 3, 4};

}

L'expression {1, 2, 3, 4} est un std::initializer_list. Pour les utiliser, l'en-têteinitializer_list> sont utilisés. Bien entendu, cet en-tête est inclus automatiquement lorsqu'un conteneur comme std::vector est utilisé.

Comparez les exemples précédents avec un exemple simple import std; ou import std::compat;. D'après ma propre expérience, je sais que les débutants ne sont pas les seuls à échouer lorsqu'ils utilisent les bons fichiers d'en-tête.

Je ne sais pas si vous l'avez remarqué, mais mon programme C++23 "Hello World" utilisait une deuxième fonctionnalité de C++23 :

C++23 propose deux surcharges pour les deux fonctions :

std::print

template< class... Args >
  void print( std::FILE* stream,
              std::format_string fmt, Args&&... args );

template< class... Args >
  void print( std::format_string fmt, Args&&... args );

std::println

template< class... Args >
  void println( std::FILE* stream,
              std::format_string fmt, Args&&... args );

template< class... Args >
  void println( std::format_string fmt, Args&&... args );

La première différence entre std::print et std::println est évident: std::println ajoute un saut de ligne. Les points suivants sont encore plus intéressants :

std::print et std::println sont des modèles variadiques. Les modèles variadiques sont des modèles qui peuvent accepter n'importe quel nombre d'arguments. Vos arguments sont parfaitement transmis. std::print et std::println sont la variante de type sécurisé de printf. À printf vous devez spécifier la chaîne de format, à std::print et std::println vous utilisez des caractères génériques dans la chaîne de format. En général, le compilateur déduit le type de données pour les espaces réservés en suivant les règles de std::format à partir de C++20 s'applique. ça semble logique std::print et std::println être en sucre syntaxique C++23 pour les chaînes de format en C++20. Voici le programme "Hello World" modifié en C++23 qui std::format utilisé.

import std;

int main() {

    // std::println("Hello World"); 
     std::cout << std::format("{:}n", "Hello World");

}

Si vous souhaitez en savoir plus sur les modèles Variadic, Perfect Forwarding et std::formaJe ne veux pas savoir, lis mes anciens articles :

Que std::print et std::println en C++23 Syntactic Sugar pour les chaînes de format en C++20 n'est pas vrai. Parce que std::print et std::println prend en charge Unicode. Permettez-moi de vous citer la proposition P2093R14 :

Un autre problème est le formatage du texte Unicode :

std::cout << "Привет, κόσμος!";

Si le codage source et d'exécution est UTF-8, cela produira le résultat attendu sur la plupart des systèmes GNU/Linux et macOS. Malheureusement sous Windows, il est presque garanti de produire du mojibake malgré le fait que le système est entièrement capable d'imprimer du Unicode, par exemple

Привет κόσμος!

même lorsqu'il est compilé avec /utf-8 en utilisant Visual C++ ([MSVC-UTF8]). Cela se produit parce que le terminal assume dans ce cas la page de codes 437 indépendamment du codage d'exécution.

Avec le document proposé

std::print("Привет, κόσμος!");

imprimera "Привет, κόσμος!" comme prévu, permettant aux programmeurs d'écrire du texte Unicode de manière portable en utilisant des fonctionnalités standard.

Les deux types std::print et std:println avoir une surcharge qui accepte n’importe quel flux de sortie. Par défaut est le flux de sortie stdout.

std::format et par conséquent aussi std::print et std::println en C++23 ont encore plus à offrir. En C++23, vous pouvez formater un conteneur de bibliothèque de modèles standard.

Le programme suivant montre comment vous pouvez générer directement un conteneur de la STL. Jusqu'à présent, aucun compilateur C++ ne prend en charge cette fonctionnalité. Seul le tout nouveau compilateur Clang avec le libc++ au lieu de libstdc++ permet d'utiliser cette fonction au moins partiellement. Dans une implémentation C++23 entièrement conforme, je pourrais std::println au lieu de std::format utiliser.

// formatVector.cpp

#include 
#include 
#include 
#include 
    
int main() {

  std::vector myInts{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::cout << std::format("{:}n", myInts);
  std::cout << std::format("{::+}n", myInts);
  std::cout << std::format("{::02x}n", myInts);
  std::cout << std::format("{::b}n", myInts);

  std::cout << 'n';

  std::vector myStrings{"Only", "for", "testing", "purpose"};
  std::cout << std::format("{:}n", myStrings);
  std::cout << std::format("{::.3}n", myStrings);

}

J'en utilise un dans cet exemple std::vector et une std::vector. Si {:} est utilisé comme espace réservé, les deux conteneurs (lignes 1 et 2) sont affichés directement. Devenez deux deux-points {::} utilisés dans l'espace réservé, les éléments du std::vector format. Le spécificateur de format suit le deuxième deux-points.

  • std::vector: Les éléments du vecteur ont un signe + {::+}sont hexadécimaux à 2 caractères avec le 0 comme caractère de remplissage {::02x} alignés et sont représentés en binaire {::b}.
  • std::vector: Chaque chaîne est tronquée à ses 3 premiers caractères : {::.3}.

La capture d'écran suivante montre la sortie du programme dans Explorateur du compilateur:



Dans mon prochain article sur la bibliothèque standard améliorée en C++23, j'utiliserai l'interface étendue de std::optional et le nouveau type de données std::expected présent pour la gestion des erreurs.


(carte)

Vers la page d'accueil



#C23 #Une #bibliothèque #standard #modularisée #deux #nouvelles #fonctions
1692749412

Facebook
Twitter
LinkedIn
Pinterest

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.