基于范围的 for 循环 (C++11 起) 中的成员解释是什么?

Eth*_*abc 6 c++ c++11 range-based-loop

我阅读了有关基于范围的循环的文档for

如果范围类型具有名为 begin 的成员和名为 end 的成员,则使用成员解释。无论成员是类型、数据成员、函数还是枚举器,也无论其可访问性如何,都会执行此操作。class meow { enum { begin = 1, end = 2}; /* rest of class */ };因此,即使存在命名空间范围的开始/结束函数,类似的类也不能与基于范围的 for 循环一起使用。

我不明白这一段。成员解释做了什么才能禁止示例类与基于范围的 for 循环一起使用?

for*_*818 6

“成员解释”是指begin_expr使用end_expr迭代类型的成员,而不是使用数组或自由函数的普通偏移beginend

数组解释不在表中,因为它仅用于数组。接下来考虑存在std::beginstd::end

可以为不公开合适的 begin() 成员函数但可以迭代的类和枚举提供 begin 的自定义重载。

现在考虑这个例子:

#include <iostream>
#include <vector>

class meow { 
    enum { begin = 1, end = 2}; 
    public:
    std::vector<int> data;
};

// non-const iterators
auto begin(meow& m){ return m.data.begin(); }
auto end(meow& m) { return m.data.end(); }
// const iterators
auto begin(const meow& m){ return m.data.begin(); }
auto end(const meow& m) { return m.data.end(); }

int main() {
    meow m;
    for (const auto& e : m) {}
}
Run Code Online (Sandbox Code Playgroud)

我们想要迭代meows data。但这不起作用。meow::begin即使和mewo::end是私有的,并且可以使用begin和函数,但仍会选择成员解释。end因此出现错误:

<source>: In function 'int main()':
<source>:17:26: error: 'meow::<unnamed enum> begin' is private within this context
     for (const auto& e : m) {}
                          ^
<source>:5:12: note: declared private here
     enum { begin = 1, end = 2};
            ^~~~~
<source>:17:26: error: 'begin' cannot be used as a function
     for (const auto& e : m) {}
                          ^
<source>:17:26: error: 'meow::<unnamed enum> end' is private within this context
<source>:5:23: note: declared private here
     enum { begin = 1, end = 2};
                       ^~~
<source>:17:26: error: 'end' cannot be used as a function
     for (const auto& e : m) {}
                          ^
Run Code Online (Sandbox Code Playgroud)

当我们删除私有枚举时,该示例工作正常:

#include <iostream>
#include <vector>

class meow { 
    //enum { begin = 1, end = 2}; 
    public:
    std::vector<int> data;
};

// non-const iterators
auto begin(meow& m){ return m.data.begin(); }
auto end(meow& m) { return m.data.end(); }
// const iterators
auto begin(const meow& m){ return m.data.begin(); }
auto end(const meow& m) { return m.data.end(); }

int main() {
    meow m;
    for (const auto& e : m) {}
}
Run Code Online (Sandbox Code Playgroud)

现场演示