L'idiome safe-bool est-il obsolète dans C ++ 11?

179

Cette réponse de @R. Martinho Fernandes montre que l'idiome safe-bool est apparemment obsolète en C ++ 11, car il peut être remplacé par un simple

explicit operator bool() const;

selon le devis standard dans la réponse §4 [conv] p3:

Une expression e peut être implicitement convertie en un type Tsi et seulement si la déclaration T t=e;est bien formée, pour une variable temporaire inventée t(§8.5). Certaines constructions de langage nécessitent qu'une expression soit convertie en valeur booléenne. Une expression eapparaissant dans un tel contexte est dite contextuellement convertie en boolet est bien formée si et seulement si la déclaration bool t(e);est bien formée , pour une variable temporaire inventée t (§8.5).

La partie en surbrillance montre clairement le "cast explicite implicite" (appelé "conversion contextuelle" dans la norme) comme @R. Martinho l'a dit.

Les "certaines constructions de langage" qui nécessitent que "cast explicite implicite" semblent être les suivantes:

  • if, while, for( §6.4 [stmt.select] p4)
  • opérateurs logiques binaires &&et ||( §5.14 [expr.log.and/or] p1pour les deux)
  • l'opérateur de négation logique !( §5.3.1 [expr.unary.op] p9)
  • opérateur conditionnel ?:( §5.14 [expr.cond] p1)
  • static_assert( §7 [dcl.dcl] p4)
  • noexcept( §15.4 [except.spec] p2)

Notre hypothèse dans le titre est-elle correcte? J'espère que nous n'avons négligé aucun inconvénient potentiel.

Xeo
la source
30
+1: J'adore ce type de question qui m'apprend de nouvelles choses sur la norme à venir.
Björn Pollex
1
Vous savez quel cast explicite implicite manque dans le standard ... renvoyer quelque chose d'un autre operator bool. Par exemple, si j'ai un shared_ptrmembre appelé p et que j'ai cette méthode operator bool() const { return p; }:, la compilation échoue. C'est stupide IMO.
David
Qu'entendez-vous par distribution "implicite explicite", @David?
Sz.

Réponses:

128

Oui. Ceci est l' exemple des problèmes avec seulement des conversions implicites définies par l'utilisateur et des opérateurs de conversion explicites définis par l'utilisateur ont été pratiquement inventés à cause de ce problème et pour remplacer tous les trucs de safe-bool par quelque chose de beaucoup plus propre et plus logique.

Chiot
la source
-5

Je n'appellerais pas cela «obsolète». Tout le monde ne fait pas encore le saut vers C ++ 11 (même pas un an ). Et même si un bon nombre de codeurs l'étaient, la possibilité de garder le code rétrocompatible serait un must, étant donné que ce genre d'idiome semble plus judicieux pour les bibliothèques que pour les programmes proprement dits.

Luis Machuca
la source
34
Je parlais uniquement en présence de C ++ 11. Cette question ne touche ni l'ancien code, ni la compatibilité descendante, ni la réticence à passer à des compilateurs compatibles C ++ 11. Notez également que C ++ 11 en lui-même n'est pas entièrement compatible avec les versions antérieures, il a introduit des changements de rupture.
Xeo
4
Je n'aurais pas pu le savoir, désolé. Je n'ai pas considéré uniquement la réponse liée au début, mais aussi le fait que la question soit taguée [c ++] et [c ++ - faq], cela m'a amené à penser que l'évaluation des deux étapes du langage était pertinente.
Luis Machuca
1
Vous avez certainement raison, je ne l'ai pas dit explicitement dans la question. Je vais éditer cela, merci pour la mise en garde.
Xeo
1
Cette réponse pourrait vraiment utiliser la mise à jour, maintenant qu'elle a presque deux ans.
Puppy
1
Je vais devoir voter pour cause de désaccord, même si je vous achèterais une bière en personne et vous dirais "hé pas de rancune". Mais de nombreux paradigmes en C ++ 11 étaient en cours de déploiement alors --std=c++0xque le dernier clou était enfoncé dans le cercueil des normes et ils ont décidé de mettre le nom sur la spécification ISO. À moins que vous ne soyez un drogué de métaprogrammation de modèles vraiment profond, les détails de la spécification C ++ 11 par rapport à ce que les gens utilisaient sont probablement sans conséquence pour vous ... ce qui signifie qu'il était plus ancien que 2011 pour presque toutes les raisons pratiques même alors. Et maintenant, à mon horloge, il est presque 2015.
HostileFork dit ne pas faire confiance à SE