usar - dato booleano en c++
¿Por qué se requiere este elenco para bool? (3)
El estándar requiere solo que el predicado sea utilizable en un contexto donde se puede convertir en un bool
. Presumiblemente, un objeto "predicado" podría tener una función operator bool
, que hizo lo correcto, ¡y un operator!
función que hizo algo totalmente sin relación. (Por supuesto, ese sería un diseño horrible, pero el estándar requiere que la biblioteca funcione como se especifica, sin importar qué tan malo sea el código de usuario). Así que g ++ se convierte en bool
, ¡y luego lo usa !
en el resultado de esa conversión (donde solo puede aplicar el operador incorporado).
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 tropecé 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 principales para hacerlo más legible.
¿Por qué usaron un bool
cast en el predicado?
En el Estándar C ++ se escribe relativo al predicado que
En otras palabras, si un algoritmo toma Predicate pred como argumento y primero como su argumento de iterador, debería funcionar correctamente en el constructo pred (* first) convertido contextualmente a bool
Las palabras "convertido contextualmente a bool" significa que si incluso una clase define una función de conversión que convierta un objeto de la clase a bool como un operador explícito, se aplicará. Considere un ejemplo de 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;
}
}
Entonces, en el contexto de la cita estándar de C ++ no veo ningún sentido al escribir la expresión
first != last && !bool( pred(*first ) )
Sería suficiente para escribir
first != last && !pred(*first )
Aquí pred se convierte contextualmente a bool.
La razón es que simplemente escribiendo !pred(*first)
podría resultar en una llamada a un operator!
sobrecargado operator!
en lugar de la llamada al explicit operator bool
.
Es interesante que esta medida se haya tomado como pred
, pero un operator&&
sobrecargado operator&&
aún se puede seleccionar en la implementación provista. first != last
debería cambiarse a bool(first != last)
para evitar también esta sobrecarga.