Xavier Lamorlette
Sommaire :
enum
: std::to_underlying
expected
transform()
transform_error()
and_then()
or_else()
optional
string
mdspan
spanstream
enum
: std::to_underlying
enum class Toto: uint8_t {…};
Toto toto {12};
uint8_t value = static_cast<uint8_t>(toto);
Faire :
uint8_t value = std::to_underlying(toto);
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();
};
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);
optional
Dans std::optional, ajout des méthodes and_then(), or_else() et transform() qui prennent en paramètre une fonction.
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 d'août 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.