2014-12-11 18 views
11

C++ 11 ha introdotto any_of a algorithm s.any_of Versus find_if

Questo sembra funzionare esattamente come find_if.

dire che ho un funtore: function<bool(int)> foo; E un array: vector<int> bar;

Sembra che queste due chiamate fanno esattamente la stessa cosa:

any_of(bar.begin(), bar.end(), foo); 

e

bar.end() != find_if(bar.begin(), bar.end(), foo); 

I più sentire che all_of e none_of possono essere eseguiti negando ilDichiarazione.

Questi algoritmi sono proprio qui per fare il confronto con end per noi, o c'è un'utilità che non capisco?

+3

Hai ragione. La libreria di GCC implementa all_of/none_of/any_of come call to last == find_if_not/last == find_if /! None_of rispettivamente –

+0

@JonathanWakely Puoi metterlo in una risposta? Mi piacerebbe accettarlo. –

risposta

16

Credo che tu abbia ragione che sono solo interfacce più convenienti per funzionalità che possono essere raggiunte in altri modi.

La proposta di aggiungerli alla standard (N2666) dice:

Questi tre algoritmi forniscono le ordinarie operazioni matematiche ∀, ∃, e ∄: data una gamma e un predicato, accertare se tale predicato è vero per tutti gli elementi; se esiste un elemento per il quale il predicato è vero; o se non esistono elementi per i quali il predicato è vero. A rigor di termini non è necessario fornire tutti e tre gli questi algoritmi (!none_of e any_of sono equivalenti), ma tutte e tre queste operazioni si sentono ugualmente fondamentali.

I nomi sono più naturale e più facile da leggere (certamente per non esperti programmatori C++) che un'espressione che coinvolge find_if e un'uguaglianza (in).libreria standard

del GCC li implementa semplicemente chiamando altre funzioni:

all_of(first, last, pred) è return last == std::find_if_not(first, last, pred);

none_of(first, last, pred) è return last == std::find_if(first, last, pred);

any_of(first, last, pred) è return !none_of(first, last, pred);

7

Si prega di notare il tipo di ritorno dei due algoritmi. Proprio come binary_search restituisce solo se l'elemento fornito può essere trovato in una sequenza ordinata, mentre lower_bound restituisce un iteratore al primo elemento non inferiore all'elemento fornito, any_of e find_if si completano a vicenda. Si noti che binary_search è (quasi) lo stesso !(val < lower_bound(a.begin(), a.end(), val))

any_of solo vi dirà se il predicato vale per ogni elemento, mentre find_if restituirà un iteratore per l'elemento che rende il predicato diventare realtà. Si noti inoltre che find_if garantisce che venga restituito un elemento iteratore all'elemento primo che rende vero il predicato, mentre any_of non presenta tali restrizioni. Quindi in teoria in alcuni casi any_of può essere più efficiente.

+3

Non penso che tu abbia veramente affrontato la domanda principale - è 'any_of' solo una scorciatoia per' find_if (:: :)! = End() '? Stai toccando l'argomento con l'ultima frase sull'efficienza, ma penso che questo meriterebbe più di un commento passeggero. – Angew

+1

@remyabel Penso che la dichiarazione fosse proprio questa, "' any_of' * può * essere più efficiente. " Ciò significa che non è necessario mantenere o restituire un iteratore in "any_of" così * if * esisteva un algoritmo più rapido rispetto al confronto lineare di ciascun elemento che poteva essere usato per "any_of". –

+2

@Angew che è la tua opinione. Non ho una risposta precisa sulla domanda ed è per questo che propongo diverse spiegazioni possibili: 1) Per coerenza (ci sono altri esempi simili nello standard) 2) per l'efficienza (qualsiasi_di ** può ** essere più efficiente) 3) facilità d'uso - 'any_if' è booleano mentre' find_if' non è il caso se ci interessa solo dell'esistenza di elementi che corrispondono al predicato possiamo usare 'any_of'. Non sono d'accordo sul fatto che tra questi l'efficienza è più importante e inoltre dubito che una qualsiasi delle implementazioni comuni sia davvero più efficiente per "any_of" –