2013-04-26 7 views
5

Ich habe einig Benutzer definiert Iteratoren, und ab und zu bekomme ich einen seltsamen Fehler, die einfach um zu arbeiten, aber ich verstehe nicht, warum ich es bin immer:Warum wird die Adresse eines Array-Elements manchmal für eine Deklaration gehalten?

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 
); 

Ich habe eine Klasse namens array_iterator mit eingebetteten typedefs row_iterator und col_iterator. Der row_iterator-Konstruktor verwendet einen col_iterator als erstes Argument. Die erste und letzte Aussage funktioniert gut. Die mittlere Anweisung schlägt mit dem folgenden Fehler zu kompilieren:

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

Schreiben & (Byte [0]) nicht das Problem lösen (nicht überraschend, da [] eine höhere Priorität hat als &). Natürlich kann ich einfach "a" für den expliziten Konstruktoraufruf col_iterator ersetzen, aber warum muss ich? Und wenn es ein Problem gibt, warum kompiliert der col_iterator-Konstruktor in der letzten Zeile?

Danke.

+2

Most Vexing Parse vielleicht? –

+1

Geben Sie ein * kurzes * Beispiel ein, das das Problem reproduziert. –

+0

Es könnte die Most Vexing Parse sein, aber ich bin mir nicht sicher. Würde die dritte Zeile nicht auf die gleiche Weise analysiert? static_cast (& bytes [0]) löst das Problem, aber nur Parens um & Bytes [0] hinzufügen nicht. Sorry, das Beispiel ist nicht mehr destilliert, aber das Problem scheint ohne Reim oder Grund zu kommen und zu gehen (d. H. Wie unterscheidet sich die dritte Zeile von der zweiten?), Also hat es meinen Versuchen widerstanden. Es sieht jedoch wie ein Parse-Fehler aus, also würde ich denken, dass es nicht darauf ankommt, was row_iterator oder col_iterator eigentlich sind. – user1806566

Antwort

2

Zunächst einmal können wir Ihr Problem mit den folgenden Zeilen eingrenzen:

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

Und die dritte Linie versteht sich als:

row_iterator base_iter_begin(col_iterator& bytes[0]); 

Und dass eine Zeile deklariert eine Funktion nimmt als Parameter ein Array von 0 Referenzen auf col_iterator und Rückgabe eines int. Es ist in der Tat ein Fall von most vexing parse wie in den Kommentaren darauf hingewiesen.

Der einfachste Weg, um es loszuwerden, ist Kopie Initialisierung statt direkter Initialisierung (Initialisierung in C++) zu verwenden:

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

die in Ihrem Fall wäre:

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

HINWEIS : Vorausgesetzt, Sie verwenden C++ 11, gibt es even more initialization rules, und Sie können die Initialisierung der Liste verwenden, um sowohl den Textbaustein als auch den ärgerlichsten Parse zu entfernen:

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