过载(c)开始/(c)结束

Overloading (c)begin/(c)end

本文关键字:结束 开始 过载      更新时间:2023-10-16

我试图为一个类重载(c)begin/(c)end函数,以便能够调用基于C++11范围的for循环。

它在大多数情况下都有效,但我无法理解和解决一个问题:

for (auto const& point : fProjectData->getPoints()){ ... }

此行返回错误:

Error C2662: 'MyCollection<T>::begin' : cannot convert 'this' pointer from 'const MyCollection' to 'MyCollection<T> &'

因为CCD_ 3是指向常量的指针。如果我把它设为非常量,它确实有效。考虑到cbegin()&将CCD_ 5精确地展开为CCD_;CCD_ 7起作用。

以下是我在MyCollection:中开发的函数(在头文件中(

/// returns the begin iterator
typename std::list<T>::iterator begin() {
    return objects.begin();
}
/// returns the begin const iterator
typename std::list<T>::const_iterator cbegin() const {
    return objects.cbegin();
}
/// returns the end iterator
typename std::list<T>::iterator end() {
    return objects.end();
}
/// returns the end const iterator
typename std::list<T>::const_iterator cend() const {
    return objects.cend();
}

有什么想法吗?

基于范围的for循环(对于类类型范围(查找beginend函数。完全不考虑cbegincend

§6.5.4【标准范围】/p1*:

[…]

  • 如果_RangeT是类类型,则在类_RangeT的作用域中查找非限定idbeginend,就像通过类成员访问查找一样(3.4.5(,并且如果其中一个(或两个(找到至少一个声明,则开始expr结束expr分别是__range.begin()__range.end()

  • 否则,begin exprend expr分别为begin(__range)end(__range),其中beginend在相关命名空间中查找(3.4.2(

对于const限定的范围,相关的成员函数也必须是const限定的(或者,如果使用了后一个选项,则应该可以用const限定的实例调用(。你需要引入额外的过载:

typename std::list<T>::iterator begin() {
    return objects.begin();
}
typename std::list<T>::const_iterator begin() const {
//                                            ~~~~^
    return objects.begin();
}
typename std::list<T>::const_iterator cbegin() const {
    return begin();
}
typename std::list<T>::iterator end() {
    return objects.end();
}
typename std::list<T>::const_iterator end() const {
//                                          ~~~~^
    return objects.end();
}
typename std::list<T>::const_iterator cend() const {
    return end();
}

演示


*措辞来自C++14,但差异与问题无关,正如所述