2015-04-07 5 views
7

cppreference mostra questa firma per std::cbegin:Perché std :: CBEGIN restituiscono lo stesso tipo di std :: iniziano

template< class C > 
constexpr auto cbegin(const C& c) -> decltype(std::begin(c)); 

non dovrebbe restituire qualcosa del genere C::const_iterator invece?

+0

Sono d'accordo che la pagina potrebbe essere un po 'più chiara su questo e non lasciare che le persone ragionino su di esso (come fatto nelle risposte date). Inoltre, potrebbe essere utile spiegare perché cbegin è stato introdotto (per garantire la costanza e non basarsi solo sulla costanza del parametro). – stefaanv

risposta

12

c è un riferimento const, quindi std::begin(c) tornerà qualunque sia la const sovraccarico C::begin() rendimenti. Per i tipi di libreria standard, questo è un const_iterator. Per un tipo di matrice, è un puntatore a const.

Si noti che questa si basa su altro utente biblioteca, non-standard definito C, in corso di attuazione in modo sano con un const sovraccarico per C::begin() che restituisce un iteratore che ti dà const l'accesso agli elementi del contenitore.

3

std::begin restituisce un iterator o const_iterator, a seconda del fatto che l'argomento è const o meno, si veda ad esempio http://en.cppreference.com/w/cpp/iterator/begin e la dichiarazione di una funzione membro begin per un contenitore standard http://en.cppreference.com/w/cpp/container/vector/begin

std::cbegin ritorna quello std::begin rendimenti (via decltype), quindi se avete un oggetto const, viene selezionato il const di sovraccarico, che a sua volta restituisce un const_iterator.

2

CBEGIN è implementata come segue:

template <class C> 
auto cbegin(const C& container)->decltype(std::begin(container)) 
{ 
    return std::begin(container); // see explanation below 
} 

corrispondente iniziare è la seguente.

template< class C > 
auto begin(C& c) -> decltype(c.begin()); //calling container's begin 

Questo modello CBEGIN accetta qualsiasi tipo di argomento che rappresenta una struttura di dati a contenitore, C, e si accede a questo argomento attraverso il suo riferimento a const parametro, contenitore. Se C è un tipo di contenitore convenzionale (ad esempio, un vettore std ::), il contenitore sarà un riferimento a una versione const di tale contenitore (ad esempio, un const std :: vector &). Richiamando la funzione di inizio non membro (fornita da C++ 11) su un contenitore const si ottiene un const_iterator e l'iteratore è ciò che restituisce questo modello.

Ad esempio, se ho utilizzato il vettore come argomento per cbegin come di seguito.

std::vector<int> v1; 
std::cbegin(v1); 

Ora, vedere come modello di deduzione è successo in questo caso, il modello (classe C) si deduce come vettori e dei parametri di cbegin (const C & container) dedotto di essere const vector<int> &. Ora dal momento che il contenitore è esso stesso è costante, restituirà la versione costante dell'inizio del vettore.

iterator begin(); 
const_iterator begin() const; //This will be used . 
const_iterator cbegin() const;