Xavier Lamorlette
Sommaire :
inline
if
et switch
enum
constexpr if
)maybe_unused
std::any
std::byte
std::optional
std::string_view
std::variant
std::get_if
std::holds_alternative
std::visit
inline
namespace A::B::C {
}
std::map<int, std::string> a_map;
auto[iter, succeeded] = a_map.insert(value);
for (const auto & [key, value]: a_map) {
…
}
if
et switch
std::map<int, std::string> a_map;
if (auto[iter, succeeded] = a_map.insert(value); succeeded) {
use_result(iter);
}
enum
enum class Toto: uint32_t {
First = 0
};
Toto toto {12};
constexpr if
)template<typename T>
auto Get_value(T t) {
if (constexpr(std::is_pointer_v<T>)) {
return * t;
} else {
return t;
}
}
maybe_unused
voip F([[maybe_unused]] bool a) {
[[maybe_unused]] bool b = a;
assert(b);
}
L'élision de copie pour les valeurs de retour (RVO: Return Value Optimisation) est garantie.
À étudier : Standard Library Utilities in C++.
std::any
std::byte
std::optional
std::string_view
std::string
ou char *
).
std::variant
Type somme : type combinant la somme disjointe des valeurs des différentes parties (comme les unions en C).
std::get_if
std::variant<int, float> int_or_float{12};
if (auto pval = std::get_if<int>(& int_or_float)) {
std::cout << "value: " << * pval << std::endl;
} else {
std::cout << "failed" << std::endl;
}
std::holds_alternative
std::variant<int, float> int_or_float{12};
if (std::holds_alternative<int>(int_or_float)) {
std::cout << "int" << std::endl;
}
std::visit
std::visit
est une fonction qui prend en paramètre un visiteur.
Exemple d'utilisation de std::visit
avec auto
:
using A_or_B = std::variant<A, B>;
std::ostream & operator << (std::ostream & os,
const A_or_B & a_or_b) {
std::visit([& os](auto const & element) {
os << element;
}, a_or_b);
return os;
}
Exemple d'utilisation de std::visit
avec des surcharges :
struct A_or_B_visitor {
std::ostream & os;
A_or_B_visitor(std::ostream & os):
os(os) {
}
void operator () (const A & a) {
os << "A: " << a;
}
void operator () (const B & b) {
os << "B: " << b;
}
};
std::ostream & operator << (std::ostream & os,
const A_or_B & a_or_b) {
std::visit(A_or_B_visitor(os), a_or_b);
return os;
}
template<typename... T>
struct Overload: T... {
using T::operator()...;
};
template<class... T>
Overload(T...) -> Overload<...>;
using A_or_B = std::variant<A, B>;
A_or_B a_or_b = A{};
auto Type_of_A_or_B = Overload {
[](A) {return "A";},
[](B) {return "B";},
[](auto) {return "unknown type";}
};
std::cout << std::visit(Type_of_A_or_B, a_or_b) << std::endl;
auto Display_A_or_B = Overload {
[](const A & a) {
std::cout << "A: " << a << std::endl;
},
[](const B & b) {
std::cout << "B: " << b << std::endl;
}
};
std::visit(Display_A_or_B, a_or_b);
En C++20, la ligne template<class... T> Overload(T...) -> Overload<...>; n'est plus nécessaire.
En C++23, on peut vérifier à la compilation que tous les types du variant sont bien pris en charge dans l'overload :
template<typename... T>
struct Overload: T... {
using T::operator()...;
consteval void operator()(auto) const {
static_assert(false, "Unsupported type");
}
};
Petite sélection :
std::vector<int> v;
std::sort(policy, v.begin(), v.end());
policy:
std::parallel::seq
: séquentielstd::parallel::par
: parallèlestd::parallel::par_unseq
: parallèle et vectorisé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.