我正在使用a vector type,它来自C库,外观类似于
struct Vec {
int *stor_begin;
int *stor_end;
int *end;
};
我试图通过创建免费的begin()
和end()
函数来为此类型启用基于范围的for循环,但是我从clang中得到了这个错误:
错误:范围类型'igraph_vector_int_t'具有'end'成员但没有'begin'成员
是否有一种方法(使用C ++ 11)为这种类型(我不能直接修改)启用基于范围的for循环?
这是一个演示问题的最小示例:
// No problems with Foo
struct Foo {
int *fooBeg;
int *fooEnd;
};
int *begin(Foo &foo) { return foo.fooBeg; }
int *end(Foo &foo) { return foo.fooEnd; }
void testFoo(Foo &foo) {
int sum = 0;
for (const auto &x : foo)
sum += x;
}
// Bar does not work because it has a member variable called 'end'
struct Bar {
int *stor_begin;
int *end;
};
int *begin(Bar &bar) { return bar.stor_begin; }
int *end(Bar &bar) { return bar.end; }
void testBar(Bar &bar) {
int sum = 0;
for (const auto &x : bar)
sum += x;
}
来自gcc 7.2 / Wandbox的错误:
prog.cc: In function 'void testBar(Bar&)':
prog.cc:26:26: error: range-based 'for' expression of type 'Bar' has an 'end' member but not a 'begin'
for (const auto &x : bar) {
^~~
prog.cc:26:26: error: expression cannot be used as a function
答案 0 :(得分:6)
g++ 8.x
和clang++ 8.x
(及更高版本)都编译您的代码:live example on godbolt.org。
这很可能是编译器错误。
如评论中的François Andrieux所述,标准规定:
1.2.2 (如果 for-range-initializer 是类类型
C
的表达式,则非限定IDbegin
和{在end
范围内查找{1}},就好像是通过类成员访问查找([basic.lookup.classref]),并且如果两者都找到至少一个声明 begin-expr 和 end-expr 分别为C
和range.begin()
;1.3.3 ,否则, begin-expr 和 end-expr 分别为
range.end()
和begin(range)
,在关联的命名空间([basic.lookup.argdep])中查找begin和end。 [注意:不执行普通的不合格查找([basic.lookup.unqual])。 —尾注]
这似乎与我的假设是错误有关。如果仅找到end(range)
和.begin
之一,则1.3.3应该使您的代码格式正确。