Pour être-fool preuve, il a besoin:Quelle fonctionnalité C++ assure l'extraction infaillible T & from optionnel <T>?
- syntaxe propre
- possibilité d'utiliser
auto
- utilisation atomique, pour éviter les erreurs accidentelles comme
if (!opt) { opt->call(); }
- aucune assertion d'exécution (EDIT : et exceptions)
- aucun avertissement de compilateur
- (facultatif) aucun vérificateur statique warnin gs
Jusqu'à présent, j'ai essayé ces 4 options (supposons avoir une optional<T> opt;
variable):
Option 0. utilisation standard
if (opt) {
opt->call();
}
- + Un code propre
- + Flux de contrôle naturel, ayant
else
déclaration - - Non atomique
- -
operator->
est exposée dans un type Nullable, il est donc facile d'appeleropt->call()
sansif
chèque
Option 1. Créer un pointeur intelligent almost_present<T>
avec _DEBUG
-uniquement le champ mutable boolean checkedPresent
qui est défini sur true
lorsque l'utilisateur le fait operator bool
:
if (almost_present<T> nonull = opt.if_present()) {
// `operator->()` and `operator T&()` assert if called without doing `if (nonull)`
nonull->call();
T& x = nonull;
}
- + flux de contrôle naturel, ayant déclaration
else
- + affirmera si l'utilisateur ne valeur vérifie pas avant le référencement, même si elle est présente
- - contrôles d'exécution
- -
almost_present<T>::operator bool() const
doit modifiercheckedPresent
champ - - mai utiliser accidentellement
nonull
dans la brancheelse
, mais c'est mineur
Option 2. basé Range-trick boucle de http://loungecpp.net/cpp/abusing-range-for/: optional<T>
ou optional<T>::if_present()
met en œuvre des méthodes begin()
et end()
pour ressembler à une collection de 0 ou 1 articles
for (auto& nonull : opt.if_present()) {
nonull.call();
}
- + syntaxe propre
- - Inconditionnel
return
à l'intérieur de toute boucle produitwarning C4702: unrechable code
(VC2017) - - Aucune déclaration
else
, doivent appelerif (!opt)
séparément, et ce n'est pas atomique - - On dirait une boucle, peut être mal interprété si
T
est une collection
Option 3. lambdas
opt.if_present([](auto& nonull) { nonull.call(); });
auto result = opt.map(
[](auto& nonull) { return nonull.call(); },
[]() { return what_if_null(); }
);
- + cela fonctionne
- - pas une syntaxe propre - difficile à lire et à déboguer
Pour l'instant, j'utilise une combinaison de « pour » boucle et « lambdas »
Presque présent me semble optionnel. – Yakk
Je n'utiliserais pas .2 et .3 pour autre chose que du divertissement. Ce genre de code est effectivement source de confusion. – Pavel
@Yakk, 'almost_present' affirme préventivement si vous avez oublié' if', donc il suffit de couvrir ce code avec 1 test. Et 'std :: optionnel' échouera seulement quand vous passerez une valeur vide, ce qui pourrait être très rare. –