重载(c)开始/(c)结束 [英] Overloading (c)begin/(c)end

查看:58
本文介绍了重载(c)开始/(c)结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I tried to overload (c)begin/(c)end functions for a class so as to be able to call C++11 range-based for loop.

在大多数情况下都可以使用,但是我无法理解和解决一个问题:

It works in most of the cases, but I don't manage to understand and solve one :

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

此行返回错误:

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

,因为 fProjectData 是指针到const。如果我将其设为非常量,则它确实可以工作。考虑到 cbegin()& cend()的精确度与 begin()& end()函数。

because fProjectData is a pointer to const. If I make it non-const, it does work. I don't understand why, considering that cbegin() & cend() are developped with exactness as begin() & end() functions.

这是我在MyCollection中开发的函数(在头文件中):

Here are my functions developped (in the header file) in 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循环(用于类类型范围)查找开始结束功能。 开始 cend 完全不考虑:

A range-based for loop (for a class-type range) looks up for begin and end functions. cbegin and cend are not considered at all:

§6.5.4 [stmt.ranged] / p1 *:

§ 6.5.4 [stmt.ranged]/p1 *:


[...]

[...]


  • 如果 _RangeT 是类类型,则 unqualified-ids 开始和<在类的范围内查找code> end ,就像按类成员访问查找(3.4.5)一样,并且如果(或两者)找到至少一个声明, begin-expr end-expr __ range.begin() __ range.end()

  • if _RangeT is a class type, the unqualified-ids begin and end are looked up in the scope of class _RangeT as if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration, begin-expr and end-expr are __range.begin() and __range.end(), respectively;

否则, begin-expr end-expr 开始(__range) end(__ range),分别在关联的命名空间(3.4.2)中查找开始 end 。 [注意:不执行普通的不合格查询(3.4.1)。 — 尾注]

otherwise, begin-expr and end-expr are begin(__range) and end(__range), respectively, where begin and end are looked up in the associated namespaces (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1) is not performed. — end note ]

对于 const 限定的范围,相关的成员函数也必须是 const 限定的(或应与<$ c $一起调用c> const 限定的实例(如果使用后一个选项)。您需要引入其他重载:

For a const-qualified range the related member functions must be const-qualified as well (or should be callable with a const-qualified instance if the latter option is in use). You'd need to introduce additional overloads:

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,但区别与所陈述的问题无关

* the wording comes from C++14, but the differences are unrelated to the problem as it is stated

这篇关于重载(c)开始/(c)结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆