2016-07-18 109 views
6

Vorrei passare un singolo lvalue a una funzione che si aspetta una coppia di iteratori e agire come se avessi passato una coppia di iteratori a un intervallo contenente solo questo valore.Iterating over a lvalue

Il mio approccio è il seguente:

#include <iostream> 
#include <vector> 

template<typename Iter> 
void iterate_over(Iter begin, Iter end){ 
    for(auto i = begin; i != end; ++i){ 
     std::cout << *i << std::endl; 
    } 
} 

int main(){ 
    std::vector<int> a{1,2,3,4}; 
    iterate_over(a.cbegin(), a.cend()); 

    int b = 5; 
    iterate_over(&b, std::next(&b)); 
} 

Questo sembra funzionare correttamente in g ++ 5.2, ma mi chiedo se questo è in realtà definito il comportamento e se ci sono eventuali problemi?

+0

Le coppie di Iterator descrivono ** intervalli **. I contenitori sono un modo per creare intervalli, ma non sono l'unico modo. Non è necessario che gli iteratori puntino agli elementi di un contenitore. –

+0

Grazie, modificato la domanda per chiarezza. – cloakedlearning

+0

Ci sono una moltitudine di domande/risposte relative/duplicate a questo, tra cui: https://stackoverflow.com/questions/14505851/è-il-uno-pasta-il-punto-intervallo-a-non-array -tipo-valido-concetto-in-c, https://stackoverflow.com/questions/2405555/string-s-s1-legal-ub, https://stackoverflow.com/questions/21411102/treating-a -singolo-oggetto-come-un-array-con-un-elemento-prendendo-uno-passato-fine-poi, ecc. – WhozCraig

risposta

11

Sì, questo è un comportamento definito. Prima abbiamo da [expr.add]/4

Ai fini di questi operatori, un puntatore ad un oggetto nonarray comporta come un puntatore al primo elemento di un array di lunghezza con il tipo di l'oggetto come suo tipo di elemento.

Quindi un singolo oggetto viene trattato come un array di lunghezza 1. Quindi abbiamo [expr.add]/5

[...] Inoltre, se i punti espressione P al ultimo elemento di un oggetto array, l'espressione (P) +1 punta oltre l'ultimo elemento dell'oggetto array, e, se l'espressione Q punta a uno oltre l'ultimo elemento di un oggetto matrice, l'espressione (Q) -1 punti fino all'ultimo elemento dell'array. Se l'operando del puntatore e il risultato puntano a elementi dello stesso oggetto matrice o uno dopo l'ultimo elemento dell'oggetto matrice, la valutazione non deve produrre un overflow; in caso contrario, il comportamento non è definito.

enfasi è mia

Quindi dal momento che il primo elemento dell'array è anche l'ultimo elemento dell'array, e l'aggiunta di 1 all'ultimo elemento dell'array ti da uno oltre l'oggetto, è legale.