¿Por qué se requiere este molde para bool?


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;
}

Me encontré con este fragmento en el código fuente de la implementación de la biblioteca estándar de C++ incluida con GCC 4.7.0. Esta es la especialización de find_if para un iterador de entrada. Limpié los guiones bajos para que fuera más legible.

¿Por qué usaron un bool fundido en el predicado?

Author: qdii, 2014-02-17

3 answers

La razón es que simplemente escribir !pred(*first) podría resultar en una llamada a un operator! sobrecargado en lugar de la llamada a explicit operator bool.

Es interesante que esta medida se haya tomado para pred, pero todavía se puede seleccionar un operator&& sobrecargado en la implementación proporcionada. first != last tendría que ser cambiado a bool(first != last) para evitar también esta sobrecarga.

 31
Author: Simple,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-17 14:41:35

El estándar solo requiere que el predicado sea utilizable en un contexto donde se puede convertir a bool. Presumiblemente, un objeto "predicado" podría tener una función operator bool , que hizo lo correcto, y una función operator! que hizo algo totalmente sin relación. (Por supuesto, eso sería horrible diseño, pero el estándar requiere que la biblioteca funcione como especificado, independientemente de lo malo que sea el código de usuario.) So g++ convierte a bool, y luego usa ! en el resultado de eso conversión (donde solo el operador puede aplicar).

 12
Author: James Kanze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-17 14:36:47

En el estándar de C++ se escribe relativo al predicado que

En otras palabras, si un algoritmo toma Predicado pred como su argumento y primero como su argumento iterador, debería funcionar correctamente en el construir pred (*primero) contextualmente convertido a bool

Las palabras "contextually converted to bool" significa que si incluso una clase define una función de conversión que convierte un objeto de la clase a bool como un operador explícito, se aplicará. Considere un ejemplo de una conversión contextual a 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;
   }
}

Así que en el contexto de la cita estándar de C++ no veo ningún sentido en la expresión escrita

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

Sería suficiente escribir

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

Aquí pred se convierte contextualmente a bool.

 2
Author: Vlad from Moscow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-17 15:57:18