Xavier Lamorlette
Sommaire :
inline
if
et switch
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);
}
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 de janvier 2023.
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.