begin()如何知道要返回哪种返回类型(const或非const)?

时间:2012-09-28 20:30:26

标签: c++ std

这非常有效:

list<int> l;
list<int>::const_iterator it;
it = l.begin();
list<int>::iterator it2;
it2 = l.begin();

我不知道的是列表“知道”它必须返回iterator begin()版本或const_iterator begin() const版本。

我正在尝试为我的容器(trie)实现迭代器,我遇到了这个问题。是不是C ++不应该通过返回类型处理区分(除非使用奇怪的技巧)?

以下是一些代码和我得到的编译器错误:

我的Trie<T>是一个模板化的三元组,可以包含任何类型。我有一个Trie<int>::iter非const迭代器和一个Trie<int>::const_iter const迭代器。在Trie类中声明(和定义)iter begin()const_iter begin() const

Trie<int> t;
Trie<int>::const_iter it;
it = t.begin();

错误:

../test/trie.cpp:181: error: no match for 'operator=' in 'it = Trie<T>::begin() [with T = int]()'
[..path..]/Trie.h:230: note: candidates are: Trie<int>::const_trie_iterator& Trie<int>::const_trie_iterator::operator=(const Trie<int>::const_trie_iterator&)

所以我相信不使用begin的非常量版本。

我打算为非const迭代器创建一个operator=(const Trie<T>::const_trie_iterator&)方法,但我没有在std lib中看到它,我必须使用const_cast迭代器。我该怎么办?

2 个答案:

答案 0 :(得分:4)

在标准容器中,非const迭代器可以隐式转换为const_iterator。返回的类型完全基于调用begin()的对象/引用的常量,在您的情况下为iterator,有一个转换允许后面的赋值。

特别是在23.2.1一般容器要求表96中,它表示X::iterator必须可转换为X::const_iterator

答案 1 :(得分:2)

list知道要返回哪种迭代器,因为定义了两个begin方法,一个用于列表是const,另一个用于何时不是。声明可能如下所示:

template<class T>
class list {
public:
    iterator<T> begin();
    const_iterator<T> begin() const;
}

在下面的示例中,将返回第一个非const迭代器,因为列表不是const:

void doSomething(list<int> &myList) {
    iterator<int> i = myList.begin();
    ...
}

在下一个示例中,列表声明为const,因此将使用返回const_iterator的第二个begin版本:

void doSomethingElse(const list<int> &myList) {
    const_iterator<int> i = myList.begin();
    ....
}

当然,迭代器总是可以强制转换为const_iterator,所以你可以在任何一个例子中声明我是一个const_iterator,但如果你试图在第二个例子中声明我是一个迭代器,你会得到一个错误因为const_iterator不能被隐式地转换为迭代器。

相关问题