2010-08-20 9 views
8

¿No pudo find_if ser una sobrecarga de find? Así es como std::binary_search y amigos lo hacen ...¿Por qué la biblioteca estándar tiene find y find_if?

+0

posible duplicado de [How to std :: find using a Compare object? ] (http://stackoverflow.com/questions/2656618/how-to-stdfind-using-a-compare-object) –

+0

@ 0A0D: ¿Cómo es esto de alguna manera un duplicado de esa pregunta? No estoy preguntando * cómo * para encontrar usando un objeto de comparación, estoy preguntando * por qué * hay una versión de función de comparación por separado. –

+0

@Billy: ver la respuesta de Steve Jessop. Responde tu pregunta y la pregunta está relacionada con dup. –

Respuesta

14

Un predicado es algo válido de encontrar, por lo que podría llegar a ambigüedades.


Considere find_if se cambia el nombre find, entonces usted tiene:

template <typename InputIterator, typename T> 
InputIterator find(InputIterator first, InputIterator last, const T& value); 

template <typename InputIterator, typename Predicate> 
InputIterator find(InputIterator first, InputIterator last, Predicate pred); 

¿Qué se hará, entonces, con:

find(c.begin(), c.end(), x); // am I finding x, or using x to find? 

En lugar de tratar de llegar a alguna solución enrevesada para diferenciar según x (que no siempre se puede hacer *), es más fácil simplemente separarlos.

* Este sería ambiguo, no importa cuál sea su régimen es o lo poderoso que puede ser †:

struct foo 
{ 
    template <typename T> 
    bool operator()(const T&); 
}; 

bool operator==(const foo&, const foo&); 

std::vector<foo> v = /* ... */; 
foo f = /* ... */; 

// f can be used both as a value and as a predicate 
find(v.begin(), v.end(), f); 

† Guardar lectura de la mente.

+0

¿Eh? No estás encontrando el predicado. Según tu edición, depende del tipo. –

+0

@ 0A0D: ¿Esto aclara? – GManNickG

+0

Sí. No tenía sentido la primera vez que lo leí. :) –

1

No puede tener el mismo nombre porque habría una ambigüedad. Supongamos que tenemos una sobrecarga de find en lugar de find_if. A continuación, supongamos:

// Pseudo-code 
struct finder 
{ 
    bool operator()(const T&) const { ... } 
    bool operator==(const finder& right) const { ... } 
} 

std::vector<finder> finders; 

finder my_finder; 

std::find(finders.begin(), finders.end(), my_finder); 

El find no tendría ninguna manera de resolver la inconsistencia: ¿Debería tratar de encontrar el finder en el envase, o el uso la finder hacer la operación de búsqueda? Para resolver este problema, crearon dos nombres de funciones.

-2

Sin duda puede implementar find en términos de find_if usando algún tipo de predicado de igualdad.

Supongo que la verdadera razón es que puede implementar find con bastante facilidad y proporcionar implementaciones especializadas eficientes para tipos típicos encontrados; si está usando find_if, el predicado que pase puede ser arbitrariamente complejo, lo que le da al implementador de la biblioteca un menor alcance de optimización.

Además, C++ tiene la filosofía de "usted no paga por lo que no usa" y normalmente esperaría que no desee pagar por una evaluación de predicados si una simple comparación lo hace.

+0

La pregunta no es acerca de implementar una en términos de la otra, sino por qué 'find_if' no es una sobrecarga de find que toma un predicado. –

3

Aquí es lo que dijo BS (El lenguaje de programación C++, 18.5.2):

Si find() y find_if() había del mismo nombre, abmiguities sorprendentes habría dado lugar. En general, el sufijo _if se usa para indicar que un algrithm toma un predicado.

En cuanto a lo que es exactamente "ambigüedad" es, Steve Jessop respondió que en su (mejor calificado) respuesta a this SO question.

(nota: esa pregunta en realidad puede calificar como la misma pregunta que esta. No soy lo suficientemente inteligente en C++ arcania para decidir).

+0

Lo llamaría relacionado, ya que la pregunta es diferente, pero las ideas son las mismas. – GManNickG

Cuestiones relacionadas