36 votes

Pourquoi cette conversion en bool est-elle nécessaire ?

template<typename InputIterator, typename Predicate>
inline InputIterator
find_if(InputIterator first, InputIterator last, Predicate pred, input_iterator_tag)
{
    while (first != last && !bool(pred(*first)))
         ++first;

    return first;
}

Je suis tombé sur cet extrait dans le code source de l'implémentation de la bibliothèque standard C++ fournie avec GCC 4.7.0. Il s'agit de la spécialisation de find_if pour un itérateur d'entrée. J'ai nettoyé les caractères de soulignement pour le rendre plus lisible.

Pourquoi ont-ils utilisé un bool sur le prédicat ?

31voto

Simple Points 4460

La raison est que le simple fait d'écrire !pred(*first) pourrait aboutir à un appel à une fonction surchargée operator! plutôt que l'appel à explicit operator bool .

Il est intéressant de noter que cette mesure a été prise pour pred mais une surcharge operator&& peut toujours être sélectionné dans l'implémentation prévue. first != last devrait être modifié en bool(first != last) pour éviter également cette surcharge.

12voto

James Kanze Points 96599

La norme exige seulement que le prédicat soit utilisable en un contexte où il peut se convertir en un bool . Vraisemblablement, un objet "prédicat" pourrait avoir un operator bool fonction, qui a fait ce qu'il fallait, et une operator! fonction qui a fait quelque chose de totalement indépendant. (Bien sûr, ce serait une horrible conception, mais la norme exige que la bibliothèque fonctionne telle que spécifié, indépendamment de la façon dont le code utilisateur est mauvais). Donc g++ convertit en bool et utilise ensuite ! sur le résultat de cette conversion (où seul l'opérateur intégré peut s'appliquer).

5voto

Potatoswatter Points 70305

Le transfert explicite vers bool assure la compatibilité avec explicit operator bool les fonctions de conversion. Le prédicat peut retourner un type de classe avec une telle conversion. Cette utilisation de explicit est nouveau dans C++11.

2voto

Vlad from Moscow Points 36219

Dans la norme C++, il est écrit par rapport au prédicat que

En d'autres termes, si un algorithme prend le prédicat pred comme argument et first comme argument de l'itérateur, il devrait fonctionner correctement dans le modèle de la construct pred(*first) contextuellement converti en bool

Les mots "contextuellement converti en bool" signifient que si même une classe définit une fonction de conversion qui convertit un objet de la classe en bool comme un opérateur explicite, elle doit être appliquée. Prenons un exemple de conversion contextuelle en bool

#include <iostream>

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

int main()
{
   if ( A() ) 
   {
      std::cout << "Here is a contextual conversion to bool" << std::endl;
   }
}

Ainsi, dans le contexte de la citation de la norme C++, je ne vois aucun sens à écrire l'expression

first != last && !bool( pred(*first ) )

Il suffirait d'écrire

first != last && !pred(*first )

Ici, pred est contextuellement converti en bool.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X