Xavier Lamorlette

C++ 23

Sommaire :

Déduction de this

Cela permet de ne plus recourir au Mixin (aussi connu sous le nom de CRTP : “Curiously Recurring Template Pattern”) pour faire du polymorphisme statique.

Au lieu de :

template <typename T>
class Base {
    void interface() {
        static_cast<T *>(this)->implementation();
    }
};

class Derived: Base<Derived> {
    void implementation();
};

On fait, en C++23 :

class Base {
    template <typename Self>
    void interface(this Self && self){
        self.implementation();
    }
};

class Derived: Base {
    void implementation();
};

STL

expected

expected permet de retourner une valeur ou une erreur :

std::expected<int, std::string> foo() {
    if … {
        return 12;
    } else {
        return std::unexpected("error text");
    }
}

auto result = foo();
if (result) {
    std::cout << "value: " << *result << std::endl;
} else {
    std::cout << "error: " << result.error() << std::endl;
}
transform()

transform() appelle une fonction si un expected contient une valeur :

std::expected<int, std::string> ga() {…}

int bu(int) {…}

auto result = ga().transform(bu);
transform_error()

transform_error() appelle une fonction si un expected contient une erreur :

std::expected<int, std::string> ga() {…}

std::string add_error_information(const std::string & error) {
    return std::string("blabla: ") + error;
}

auto result = ga().transform_error(add_error_information);
and_then()

and_then() appelle une fonction si un expected contient une valeur, la fonction appelée retournant elle-même un expected, ce qui permet de chainer des fonctions sans devoir tester si les valeurs intermédiaires sont des erreurs :

std::expected<int, std::string> ga() {…}

std::expected<int, std::string> bu(int) {…}

auto result = ga().and_then(bu);
if (result) {
    std::cout << "value: " << *result << std::endl;
} else {
    std::cout << "error: " << result.error() << std::endl;
}
or_else()

À l'inverse de transform(), or_else() appelle une fonction si un expected contient une erreur :

std::expected<int, std::string> ga() {…}

std::expected<int, std::string> handle_error(const std::string & error) {
    std::cerr << "Error: " << error << std::endl;
    return std::unexpected(error);
}

auto result = ga().or_else(handle_error);

On combine efficacement and_then() et or_else() :

std::expected<int, std::string> ga() {…}

std::expected<int, std::string> bu(int) {…}

std::expected<int, std::string> handle_error(const std::string & error) {
    std::cerr << "Error: " << error << std::endl;
    return std::unexpected(error);
}

auto result = ga().and_then(bu).or_else{handle_error);

Ajouts à optional

Dans std::optional, ajout des méthodes and_then(), or_else() et transform() qui prennent en paramètre une fonction.

Ajout à string

std::string::contains()

mdspan

std::mdspan est un “multidimensional span”.

spanstream

Un std::spanstream est un stream auquel on fournit un span à utiliser :

 char buffer[128] { 0 };
std::span span_buffer(buffer);
std::basic_spanstream span_streanm(span_buffer);
span_streanm << "foo bar";

La dernière mise à jour de cette page date de mai 2024.

Le contenu de ce site est, en tant qu'œuvre originale de l'esprit, protégé par le droit d'auteur.
Pour tout commentaire, vous pouvez m'écrire à xavier.lamorlette@gmail.com.