web-dev-qa-db-fra.com

Quand puis-je utiliser un opérateur explicite bool sans cast?

Ma classe a une conversion explicite en bool:

struct T {
    explicit operator bool() const { return true; }
};

et j'en ai un exemple:

T t;

Pour l'assigner à une variable de type bool, j'ai besoin d'écrire un cast:

bool b = static_cast<bool>(t);
bool b = bool(t);
bool b(t);  // converting initialiser
bool b{static_cast<bool>(t)};

Je sais que je peux utiliser mon type directement dans un conditionnel sans transtypage, malgré le qualificatif explicit:

if (t)
    /* statement */;

Où puis-je utiliser t comme bool sans transtypage?

31
Toby Speight

La norme mentionne les endroits où une valeur peut être " convertie contextuellement en bool". Ils se répartissent en quatre groupes principaux:

Déclarations

  • if (t) /* statement */;
    
  • for (;t;) /* statement */;
    
  • while (t) /* statement */;
    
  • do { /* block */ } while (t);
    

Expressions

  • !t
    
  • t && t2
    
  • t || t2
    
  • t ? "true" : "false"
    

Tests de compilation

L'opérateur doit être constexpr pour ceux-ci:

  • static_assert(t);
    
  • noexcept(t)
    
  • if constexpr (t)
    

Algorithmes et concepts

  • NullablePointer T
    

    Partout où la norme requiert un type satisfaisant ce concept (par exemple, le type pointer d'un std::unique_ptr), il peut être converti en contexte. De plus, la valeur de retour des opérateurs d'égalité et d'inégalité d'un NullablePointer doit être convertible contextuellement en bool.

  • std::remove_if(first, last, [&](auto){ return t; });
    

    Dans tout algorithme avec un paramètre de modèle appelé Predicate ou BinaryPredicate, l'argument prédicat peut renvoyer un T.

  • std::sort(first, last, [&](auto){ return t; });
    
    Dans tout algorithme avec un paramètre de modèle appelé Compare, l'argument comparateur peut renvoyer un T.

( source1 , source2 )


N'oubliez pas qu'un mélange d'opérateurs de conversion const et non const peut provoquer de la confusion:

39
Toby Speight