如果range_expression是类类型C的表达式,且同时具有 名为begin的成员和名为end的成员(无论类型是 该成员的可访问性),则begin_expr为__range.begin(), end_expr是__range.end();
如果范围类型具有名为的成员,则使用成员解释 开始,一个名为end的成员。不论是否 member是类型,数据成员,函数或枚举数,无论 其可访问性。因此,像喵喵类这样的类{枚举{begin = 1, end = 2}; / *课程的其余部分* /};不能与基于范围的 即使存在命名空间范围的开始/结束功能,for循环也是如此。
理解是否正确,开始和结束应该仅是范围类型(可能返回迭代器类型)的成员函数的名称?好奇地了解缺乏针对此约束的任何解决方法的技术原因。
答案 0 :(得分:4)
您需要提供可以通过argument-dependent lookup找到的非成员begin
和end
函数(或其他可调用对象),或显式地具有成员函数(或可调用对象)分别命名为begin
和end
,它们不带参数,并且返回类似迭代器的对象(即,它们应支持后缀++
和取消引用*
,当然可以使用==
。
由于“技术原因”,这是因为基于范围的for
循环只是普通迭代器for
循环的语法糖。并且编译器必须知道调用“ begin”和“ end”迭代器的函数。
答案 1 :(得分:3)
理解是否正确,开始和结束应该仅是范围类型(可能返回迭代器类型)的成员函数的名称?
否;实际上,即使它们不是成员函数,大多数也完全可以用作开始/结束迭代器对!
这里是一个使用数据成员的人:
struct A {
A() : begin([this] { return array; }), end([this] { return array + 3; }) {}
int array[3];
std::function<int*()> begin;
std::function<int*()> end;
};
枚举器没有任何意义,并且无法通过.
访问类型。命名类型或带有begin
和end
的枚举数的类型应该是非常稀有的,这可能就是为什么没有引入不排除枚举数的特殊规则的原因。