C++ 为什么数组元素的地址有时会被误认为是声明?

C++ 为什么数组元素的地址有时会被误认为是声明?,c++,arrays,reference,most-vexing-parse,C++,Arrays,Reference,Most Vexing Parse,我有一些用户定义的迭代器,偶尔会出现一个奇怪的错误,很容易解决,但我不明白为什么会出现这个错误: 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_ite

我有一些用户定义的迭代器,偶尔会出现一个奇怪的错误,很容易解决,但我不明白为什么会出现这个错误:

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
  );
我有一个名为array_iterator的类,它嵌入了typedefs row_iterator和col_iterator。行迭代器构造函数将列迭代器作为其第一个参数。第一个和最后一个语句工作得很好。中间语句无法编译,错误如下:

test-2d-iterators.cc:780: error: declaration of 'bytes' as array of references
写入&(字节[0])并不能解决问题(毫不奇怪,因为[]的优先级高于&)。当然,我可以用“a”代替显式col_迭代器构造函数调用,但是为什么我必须这样做呢?如果有问题,为什么最后一行中的col_迭代器构造函数要编译


谢谢。

首先,我们可以将您的问题缩小到以下几行:

struct row_iterator { ... };
typedef unsigned* col_iterator;
unsigned bytes[5];
row_iterator base_iter_begin(col_iterator(&bytes[0]));
第三行被理解为:

row_iterator base_iter_begin(col_iterator& bytes[0]);
其中一行声明了一个函数,该函数将引用col_迭代器的0数组作为参数,并返回一个int。这确实是注释中指出的一个例子

消除它的最简单方法是使用复制初始化而不是直接初始化(C++中的初始化):

在你的情况下,这将是:

array_iterator::row_iterator base_iter_begin = array_iterator::row_iterator(array_iterator::col_iterator( &bytes[0] ), width, pitch );
注意:如果您使用的是C++11,则有,并且您可以使用列表初始化来摆脱样板文件和最麻烦的解析:

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

可能是最令人烦恼的解析?发布一个简短的例子来重新说明这个问题。它可能是最令人烦恼的解析,但我不确定。第三行不也是这样解析的吗?静态_cast(&bytes[0])解决了这个问题,但仅仅在&bytes[0]周围添加paren并不能解决这个问题。很抱歉,这个例子没有更多的提炼,但是这个问题似乎来去匆匆,没有任何原因(例如,第三行和第二行有何不同?),所以它抵制了我的尝试。当然,这看起来像是一个解析错误,所以我认为这并不取决于行迭代器或列迭代器的实际位置。你能把它转换成一个解析错误吗?删除包含的
array\u迭代器
类,删除除构造函数以外的所有功能,然后查看问题是否仍然存在,如果没有,问题何时消失。如果它仍然存在,则发布剩余的代码,这应该不会太多。
array_iterator::row_iterator base_iter_begin{array_iterator::col_iterator(&bytes[0]), width, pitch};