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

Why is the address of an array element sometimes mistaken for a declaration?

本文关键字:误认为 认为是 声明 数组元素 地址 为什么      更新时间:2023-10-16

我有一些用户定义的迭代器,每隔一段时间我得到一个奇怪的错误,很容易解决,但我不明白为什么我得到它:

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的类,其中嵌入了row_iterator和col_iterator类型。row_iterator构造函数的第一个参数是col_iterator。第一个和最后一个表述都没问题。中间语句编译失败,出现以下错误:

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

写入&(bytes[0])并不能解决问题(这并不奇怪,因为[]的优先级比&高)。当然,我可以用"a"代替显式的col_iterator构造函数调用,但为什么我必须这样做呢?如果存在问题,为什么最后一行的col_iterator构造函数会编译?

谢谢。

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

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

那一行声明了一个函数,该函数的形参是一个包含0个col_iterator引用的数组,并返回int类型。正如在评论中指出的那样,这确实是一个最令人烦恼的解析。

消除它的最简单的方法是使用复制初始化而不是直接初始化(c++中的初始化):
row_iterator base_iter_begin = row_iterator(col_iterator(&bytes[0]));

在你的例子中应该是:

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