C++11中的范围for循环中成员解释是什么?

6
我阅读了这篇有关基于范围的for循环的文档
引用如下:
如果范围类型具有名为begin和end的成员,则使用成员解释。无论成员是类型、数据成员、函数还是枚举器,无论其是否可访问,都会这样做。因此,像class meow { enum { begin = 1, end = 2}; /* rest of class */ }; 这样的类即使存在作用域的begin/end函数,也不能与基于范围的for循环一起使用。
我不理解这段话。成员解释是如何禁止示例类与基于范围的for循环一起使用的?

7
就像引文所说的那样,它会在“meow”中查找名称为“begin”和“end”的内容,由于它们不是返回迭代器的函数,因此范围基于for循环无法工作。 - NathanOliver
1个回答

6
"成员解释"是指使用迭代类型的成员对比使用数组中的纯偏移量或者 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) {}
}

我们希望迭代 "meow" 的数据。但它不起作用。即使 "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) {}
                          ^

当我们移除私有枚举时,示例可以正常工作:

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

现场演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接