如何使用两个函数,一个返回iterator,另一个返回const_iterator
所以我有一个名为 find 的函数,它有两个版本:
template <typename T>
typename btree<T>::iterator btree<T>::find(const T& elem)
{
//Implementation
}
另一个是 const_iterator 版本:
template <typename T>
typename btree<T>::const_iterator btree<T>::find(const T& elem) const
{
//Implementation
}
在我的测试文件中,当我执行
btree<char>::iterator it = myTree.find('M');
“一切正常”时,但是当我使用 const_iterator 版本时:
btree<char>::const_iterator it = myTree.find('M');
它给了我错误
错误:请求从“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
So I have a function called find, which has two versions:
template <typename T>
typename btree<T>::iterator btree<T>::find(const T& elem)
{
//Implementation
}
and the other is the const_iterator version:
template <typename T>
typename btree<T>::const_iterator btree<T>::find(const T& elem) const
{
//Implementation
}
In my test file when I do
btree<char>::iterator it = myTree.find('M');
Everything works fine, however when I use the const_iterator version:
btree<char>::const_iterator it = myTree.find('M');
It gives me the error
error: conversion from 'btree_iterator' to non-scalar type 'const_btree_iterator' requested
Which obviously means that find is only ever using the iterator (non const
) version. I know that C++ is supposed to call the const_iterator
version automatically - if I had done everything right. So the question is, what might I be doing wrong?
The iterator classes are:
class btree_iterator
and class const_btree_iterator
which is just a copy paste of btree_iterator
with the names changed
Here are the full source code:
btree_iterator.h (includes const_btree_iterator) http://pastebin.com/zQnj9DxA
btree.h http://pastebin.com/9U5AXmtV
btree.tem http://pastebin.com/U9uV3uXj
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所有标准容器都实现了非常量迭代器到常量迭代器的转换(如容器概念的要求中指定的):
你需要像这样的转换构造函数:
我也加入了赋值运算符,但我认为它是多余的
All the standard containers implement conversion of non-const to const iterators (as specified in the requirements for the Container concept):
You need conversion constructor like so:
I threw in the assignment operator too but I suppose it is redundant
这里重要的一点是,重载决策仅基于函数的参数而不是结果来执行。在您的特定情况下,您有两个不同的重载,区别在于隐式
this
在其中一个重载中是常量,只要该方法所在的对象或引用的静态类型,就会拾取该重载称为常数。如果您想强制分派常量重载,您可以获取一个 const 引用,然后调用该引用:
您应该在实际代码中避免使用此构造,即使您将其用于测试目的。原因是 const 和非常量重载应该具有相同的语义,因此行为应该相同。
另请注意,在标准容器中,存在从
iterator
到const iterator
的隐式转换,以支持直接在非常量容器上使用const_iterator
。你应该做同样的事情,也就是说,如果你提供从iterator
到const_iterator
的隐式转换,那么你可以只写:... 它会工作(不会测试
find
方法,但将允许您验证const_iterator
行为)The important bit here is that overload resolution is performed based only on the arguments to the function and not the result. In your particular case you have two different overloads and the difference is that the implicit
this
is constant in one of them, that overload will be picked up whenever static type of the object or reference on which the method is called is constant.If you want to force dispatch to the constant overload, you can obtain a const reference and then call on that reference:
You should avoid this construct in real code, even if you use it for testing purposes. The reason is that the const and non-const overloads should have the same semantics and thus the behavior should be the same.
Also note that in standard containers, there is an implicit conversion from
iterator
toconst iterator
to support usingconst_iterator
s directly on non-const containers. You should do the same, that is, if you provide an implicit conversion fromiterator
toconst_iterator
, then you can just write:... and it will work (will not test the
find
method, but will allow you to verify theconst_iterator
behavior)