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

What is member interpretation in Range-based for loop (since C++11)?

我阅读了 this documentation 基于范围的 for 循环:

The member interpretation is used if the range type has a member named begin and a member named end. This is done regardless of whether the member is a type, data member, function, or enumerator, and regardless of its accessibility. Thus a class like class meow { enum { begin = 1, end = 2}; /* rest of class */ }; cannot be used with the range-based for loop even if the namespace-scope begin/end functions are present.

这段我没看懂。成员解释如何禁止示例 class 与基于范围的 for 循环一起使用?

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

数组解释已关闭 table,因为它仅用于数组。接下来考虑有 std::beginstd::end:

Custom overloads of begin may be provided for classes and enumerations that do not expose a suitable begin() member function, yet can be iterated.

现在考虑这个例子:

#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) {}
}

我们要迭代 meows data。但它不起作用。选择成员解释,即使 meow::beginmewo::end 是私有的并且可以使用 beginend 函数。因此错误:

<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) {}
                          ^

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

#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) {}
}

Live Demo