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”.
Il permet d'utiliser des index multidimensionnels sur un tableau unidimensionnel.
std::vector<uint32_t> onedimensional = {1, 2, 3, 4, 5, 6};
std::mdspan<uint32_t, std::dextents<size_t, 2>> matrix = std::mdspan(onedimensional.data(), 2, 3);
uint32_t value = matrix[1, 2];
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 mars 2025.
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.