2013-04-26 7 views
5

Ho alcuni iteratori definiti dall'utente, e di tanto in tanto sono un errore di strano che è facile da aggirare, ma non capisco perché sto ricevendo:Perché l'indirizzo di un elemento dell'array viene a volte scambiato per una dichiarazione?

uint8_t bytes[pitch*height]; 

array_iterator::col_iterator a(&bytes[0]); 

array_iterator::row_iterator base_iter_begin(
    array_iterator::col_iterator(&bytes[0]), width, pitch); 

array_iterator::row_iterator base_iter_end(
    array_iterator::col_iterator(&bytes[pitch*height]), width, pitch 
); 

ho una classe chiamato array_iterator con typedefs incorporato row_iterator e col_iterator. Il costruttore row_iterator prende un col_iterator come primo argomento. La prima e l'ultima istruzione funzionano bene. La dichiarazione di mezzo non riesce a compilare con il seguente errore:

test-2d-iterators.cc:780: error: declaration of 'bytes' as array of references 

Scrittura & (byte [0]) non risolve il problema (non a caso, dal momento che [] ha precedenza maggiore rispetto &). Ovviamente, posso semplicemente sostituire "a" per la chiamata esplicita del costruttore col_iterator, ma perché devo? E se c'è un problema, perché compila il costruttore col_iterator nell'ultima riga?

Grazie.

+2

Most Vexing Parse forse? –

+1

Posta un * breve * esempio che riprova il problema. –

+0

Potrebbe essere il peggior fastidio, ma non ne sono sicuro. La terza riga non sarebbe analoga allo stesso modo? static_cast (& byte [0]) risolve il problema, ma l'aggiunta di parenti in giro e byte [0] no. Spiacente, l'esempio non è più distillato, ma il problema sembra andare e venire senza alcuna rima o ragione (cioè, qual è la terza linea diversa dalla seconda?), Quindi ha resistito ai miei tentativi. Certamente sembra un errore di analisi, quindi, penso che non dipenda da cosa siano effettivamente row_iterator o col_iterator. – user1806566

risposta

2

Prima di tutto, siamo in grado di restringere il problema alle seguenti linee:

struct row_iterator { ... }; 
typedef unsigned* col_iterator; 
unsigned bytes[5]; 
row_iterator base_iter_begin(col_iterator(&bytes[0])); 

E la terza linea è intesa come:

row_iterator base_iter_begin(col_iterator& bytes[0]); 

E quella riga dichiara una funzione prendendo come parametro un array di 0 riferimenti a col_iterator e restituisce un int. Si tratta in effetti di most vexing parse come indicato nei commenti.

Il modo più semplice per sbarazzarsi di esso è quello di utilizzare la copia di inizializzazione invece di inizializzazione diretta (inizializzazione in C++):

row_iterator base_iter_begin = row_iterator(col_iterator(&bytes[0])); 

che nel tuo caso sarebbe:

array_iterator::row_iterator base_iter_begin = array_iterator::row_iterator(array_iterator::col_iterator(&bytes[0]), width, pitch); 

NOTA : Se si utilizza C++ 11, esistono even more initialization rules ed è possibile utilizzare l'inizializzazione dell'elenco per eliminare sia lo standard di stampa che l'analisi più irritante:

array_iterator::row_iterator base_iter_begin{array_iterator::col_iterator(&bytes[0]), width, pitch}; 
Problemi correlati