2013-04-26 46 views
5

我有一些用户定义的迭代器,和每一个现在,然后我得到一个奇怪的错误,很容易解决,但我不明白为什么我得到它:为什么数组元素的地址有时会被误认为声明?

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。 row_iterator构造函数将col_iterator作为其第一个参数。第一个和最后一个声明工作得很好。中间语句失败,错误如下进行编译:

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

写作&(字节[0])不解决问题(这并不奇怪,因为[]的优先级高于&)。当然,我可以用“a”代替显式的col_iterator构造函数调用,但为什么我必须?如果出现问题,为什么最后一行中的col_iterator构造函数会被编译?

谢谢。

+2

最烦人的解析也许? – 2013-04-26 01:52:12

+1

发布可重现问题的* short *示例。 – 2013-04-26 02:20:57

+0

它可能是最烦人的解析,但我不确定。第三行不会以同样的方式解析吗? static_cast (&bytes [0])解决了这个问题,但只是在&bytes [0]周围添加parens不会。对不起,这个例子并没有更多提炼出来,但问题似乎没有任何韵律或理由(即第三行与第二行不同),所以它抵制了我的尝试。不过,它看起来像一个分析错误,所以我认为它不依赖于row_iterator或col_iterator的实际内容。 – user1806566 2013-04-26 03:10:41

回答

2

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

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_iterator的0引用的数组,并返回一个int。正如评论中指出的那样,确实是most vexing parse的一个例子。

摆脱它的最简单方法是使用复制初始化,而不是直接初始化(初始化在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,有even more initialization rules,你可以使用列表初始化来摆脱样板和最令人头疼的解析:

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