2013-03-20 10 views
7

Se ho intervallo (coppia di 2 iteratori) c'è un modo per scrivere "per ogni" ciclo per quell'intervallo, non un array o un contenitore raw.Can range based per il ciclo su un intervallo

Qualcosa di simile a questo:

auto rng = std::equal_range(v.begin(),v.end(),1984); 
for(const auto& elem: rng) { 
    // ... 
} 
+1

È possibile utilizzare Boost? – inf

+1

Se è possibile utilizzare boost, boost ha un iteratore di intervallo. – OmnipotentEntity

+0

sì, posso, e lo faccio :) <3 boost – NoSenseEtAl

risposta

13

Come da Why was pair range access removed from C++11? è possibile utilizzare un adattatore, ad es. l'as_range alla risposta accettata, boost::make_iterator_range, o lascia la tua:

template<typename It> struct range { 
    It begin_, end_; 
    It begin() const { return begin_; } 
    It end() const { return end_; } 
}; 
template<typename It> range<It> as_range(const std::pair<It, It> &p) { 
    return {p.first, p.second}; 
} 

auto rng = std::equal_range(v.begin(),v.end(),1984); 
for(const auto& elem: as_range(rng)) 
    ... 

Il motivo per cui questo non è applicabile in generale è che per ogni Alastair Meredith's paper, degli algoritmi,

  • mismatch e partition_copy cambio una coppia di iteratori da diverse gamme;
  • minmax restituisce una coppia di oggetti che potrebbero non essere affatto iteratori e, in caso contrario, non garantisce che formino un intervallo;
  • minmax_element può restituire un intervallo, ma può anche restituire una gamma invertito (ad esempio, su una gamma reverse-ordinato minmax_element tornerà {prev(last), first};.
  • equal_range è garantito per restituire un intervallo di
+0

sai quali funzioni restituiscono un intervallo non valido? Intendo in std, non user junk: P – NoSenseEtAl

+0

@NoSenseEtAl buona domanda, vedi sopra. Le gamme – ecatmur

2

non credo che funzionerà come quello fuori dalla scatola come equal_range restituisce una coppia di iteratori po ', il ciclo per più di gamma in base alla documentation sono:

The begin_expr and end_expr are defined to be either: 
If (__range) is an array, then (__range) and (__range + __bound), where __bound is the array bound 
If (__range) is a class and has either a begin or end member (or both), then begin_expr is __range.begin() and end_expr is __range.end(); 
Otherwise, begin(__range) and end(__range), which are found based on argument-dependent lookup rules with std as an associated namespace. 

Direi che è possibile definire le funzioni begin e end che eseguono la coppia di iteratori e restituiscono il primo e il secondo in modo prospettico.

0

Quali std::equal_range rendimenti è semplicemente uno std :: coppia. Lo standard non copre alcun metodo per iterare su queste cose.

Cosa si consiglia di leggere è "Iterators must go" presentazione di Alexandrescu. Here is the video. un'eccellente lettura su un altro el modo egant per iterare i contenitori usando i Ranges.

Gli intervalli sono implementati nella sua libreria Loki.

+0

sono implementate in boost e sono in fase di std, quindi chiunque voglia usarle dovrebbe usare boost – NoSenseEtAl

+0

Sono a conoscenza di Boost.Range tuttavia non l'ho preso abbastanza bene, non ero sicuro se sono uguali a quelli di Alexandrescu. Ecco perché non ho suggerito Boost.Range. Sei sicuro che siano la stessa cosa? –

+0

no, ma idk la differenza, se i valori incrementali/std sono semplicemente coppie di iter .... ma non so davvero i dettagli ... – NoSenseEtAl

0
#include <vector> 
#include <algorithm> 
#include <iostream> 

template <typename I> 
struct range_adapter { 
    std::pair<I, I> p; 

    range_adapter(const std::pair<I, I> &p) : p(p) {} 

    I begin() const { return p.first; } 
    I end() const { return p.second; } 
}; 

template <typename I> 
range_adapter<I> in_range(const std::pair<I, I> &p) 
{ 
    return range_adapter<I>(p); 
} 

int main() 
{ 
    std::vector<int> data { 1, 2, 2, 3, 3, 3, 4 }; 

    auto r = std::equal_range(data.begin(), data.end(), 2); 

    for (const auto &elem : in_range(r)) 
    { 
     std::cout << elem << std::endl; 
    } 
} 
Problemi correlati