Ce qui suit est une ébauche d'un article à venir.
À partir de C++ 17, il devient possible d'évaluer des conditions à la compilation et d'exclure, sur la base de ces conditions, des blocs de code (qui doivent toutefois être bien formés). Par exemple :
//
// On veut un array<T,N> si N*sizeof(T) est moins de SEUIL bytes, et un vector<T> de N éléments sinon,
// ce qui explique le type de retour... qui sera déterminé par if constexpr
//
template <class T, int N, int SEUIL = 4096>
auto creer_tampon_temporaire() {
if constexpr(NB * sizeof(T) < SEUIL)
return array<T,N> {};
else
return vector<T>(N);
}
Ceci permet entre autres de remplacer plusieurs recours à enable_if, qui est quelque peu obscur, par du code bien plus simple à comprendre et à expliquer :
Avec enable_if | Avec if constexpr |
---|---|
|
|
|
|
C'est simple, direct et extrêmement utile.
Comme le fait remarquer Nicolai Josuttis (propos rapportés par Peter Sommerlad dans https://twitter.com/PeterSommerlad/status/1034726303440748544), seule la condition doit être évaluable à la compilation; il est possible de profiter de la partie initialisation à l'exécution, ce qui permet par exemple d'écrire :
template <class C, class M>
auto process_synchronized(const C &c, M &mut) {
if constexpr(lock_guard _ { mut }; is_pointer_v<typename C::value_type>) {
// opérer de manière synchronisée sur les éléments de c (qui sont des pointeurs)
} else {
// opérer de manière synchronisée sur les éléments de c (qui ne sont pas des pointeurs)
}
}
Quelques liens pour enrichir le propos.