如何使用两个函数,一个返回迭代器,另一个返回const_iterator

Arv*_*vin 7 c++ iterator compiler-errors const

所以我有一个名为find的函数,它有两个版本:

template <typename T> 
typename btree<T>::iterator btree<T>::find(const T& elem)
{
    //Implementation
}
Run Code Online (Sandbox Code Playgroud)

另一个是const_iterator版本:

template <typename T> 
typename btree<T>::const_iterator btree<T>::find(const T& elem) const
{
    //Implementation
}
Run Code Online (Sandbox Code Playgroud)

在我的测试文件中,当我这样做

btree<char>::iterator it = myTree.find('M');
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当我使用const_iterator版本时:

btree<char>::const_iterator it = myTree.find('M');
Run Code Online (Sandbox Code Playgroud)

它给了我错误

错误:从'btree_iterator'转换为请求的非标量类型'const_btree_iterator'

这显然意味着find只使用迭代器(非const)版本.我知道C++应该const_iterator自动调用版本 - 如果我做的一切正确的话.所以问题是,我可能做错了什么?

迭代器类是:

class btree_iterator而class const_btree_iterator这只是一个复制粘贴btree_iterator改变与名

以下是完整的源代码:
btree_iterator.h(包括const_btree_iterator)http://pastebin.com/zQnj9DxA
btree.h http://pastebin.com/9U5AXmtV
btree.tem http://pastebin.com/U9uV3uXj

seh*_*ehe 9

所有标准容器都实现了非const到const迭代器的转换(在Container概念的要求中指定):

用于迭代容器元素的迭代器类型.迭代器的值类型应该是容器的值类型.必须存在从迭代器类型到const迭代器类型的转换.

你需要像这样的转换构造函数:

class btree_iterator;
class const_btree_iterator
{
       // ....
       public:
              const_btree_iterator(const btree_iterator& rhs) { /* .... */ }
//optionally: const_btree_iterator& operator=(const btree_iterator& rhs) { /* .... */ }
};
Run Code Online (Sandbox Code Playgroud)

我也投入了赋值运算符,但我认为它是多余的


Dav*_*eas 5

这里重要的一点是,只根据函数的参数而不是结果执行重载决策.在您的特定情况下,您有两个不同的重载,不同之处在于隐式this在其中一个中是常量,只要调用该方法的对象或引用的静态类型是常量,就会获取重载.

如果要强制调度常量重载,可以获取const引用,然后调用该引用:

btree<char> const & r = myTree;
btree<char>::const_iterator it = r.find('M');
Run Code Online (Sandbox Code Playgroud)

您应该在实际代码中避免使用此构造,即使您将其用于测试目的.原因是const和非const重载应该具有相同的语义,因此行为应该是相同的.

另请注意,在标准容器中,有一个隐式转换iterator,const iterator以支持const_iterator在非const容器上直接使用s.你应该做的一样,那就是,如果你提供从隐式转换iterator到const_iterator,那么你可以这样写:

btree<char>::const_iterator it = myTree.find('M');
Run Code Online (Sandbox Code Playgroud)

...它会工作(不会测试find方法,但会让你验证const_iterator行为)