STL 迭代器和“const”
当我使用迭代器时,我遇到了似乎对 const 进行某种隐式转换的问题。我不太确定哪个代码是相关的(如果我这样做的话,我可能不会问这个问题!)所以我会尽力说明我的问题。
typedef set<SmallObject> Container; //not const
void LargeObject::someFunction() { //not const
Container::iterator it; //not const
for (it = c.begin(); it != c.end(); ++it) { //assume c is a "Container"
(*it).smallObjectFunction(); //not a const function
}
}
但是我总是收到以下错误:
error: passing 'const SmallObject' as 'this' argument of 'int SmallObject::smallObjectFunction()' discards qualifiers
但是,如果我将其转换为 ((SmallObject)(*it).smallObjectFunction();
那么我就会摆脱错误消息。
我唯一能想到的就是是否以某种方式
bool operator< (const SmallObject &a) const;
导致迭代器返回 const 对象?这里有任何帮助或解释吗?
I have a problem with what appears to be some sort of implicit casting to const when I use iterators. I'm not really sure which code is relevant (if I did I probably wouldn't be asking this question!) so I will try my best to illustrate my problem.
typedef set<SmallObject> Container; //not const
void LargeObject::someFunction() { //not const
Container::iterator it; //not const
for (it = c.begin(); it != c.end(); ++it) { //assume c is a "Container"
(*it).smallObjectFunction(); //not a const function
}
}
However I always get the following error:
error: passing 'const SmallObject' as 'this' argument of 'int SmallObject::smallObjectFunction()' discards qualifiers
However, if I cast it as ((SmallObject)(*it).smallObjectFunction();
then I get rid of the error message.
The only thing I can figure is that somehow the definition of
bool operator< (const SmallObject &a) const;
is somehow causing the iterator to return const objects. Any help or explanation here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
集合和映射根据排序条件保持元素的顺序。为了使用户代码不破坏不变量,映射的
key
和集合中的整个元素必须是常量。您的问题是存储的元素不是SmallObject
而是const SmallObject
。如果这不受限制,您可能会遇到:
问题不仅在于现在集合元素不按顺序排列,而且取决于树的构建方式,可能存在集合中存在但无法找到的元素。
Sets and maps keep the elements in order according to the sort condition. For user code not to break invariants, the
key
of the map and the whole element in the set must be constant. Your problem is that the stored element is not aSmallObject
but aconst SmallObject
.If this was not limited you could have:
The problem there is not only that now the set element would not be in order, but that depending on how the tree was built there could be elements that are present in the set but cannot be found.
您的代码不愚蠢,并且可以使用一致的STL实现进行干净地编译,具体取决于您的STL实现所做的一些设计决策。 C++03 标准没有指定 set::iterators 的引用 typedef 应该是什么(在我看来,它们应该是非常量引用)。因此,继续做你所做的事情,但插入一个const_cast:
它比擦除和重新插入更高效、更清晰。有关此问题的更广泛讨论,请查看 Herb Sutter 的“More Exceptional C++”中的第 8 条。
在这种情况下执行 const_cast 是完全安全的,而且这种风格也不错,只需确保您不更改确定顺序的字段的值即可。如果类的接口使得很难验证您没有更改顺序,那么该接口可能设计得不好。
Your code is not stupid and could compile cleanly with a conformant STL implementation, depending on some design decisions that your STL implementation made. The C++03 Standard does not specify what the reference typedef should be for set::iterators (in my opinion, they should be non-constant references). So keep doing what you do, but insert a const_cast:
It is more efficient and much clearer than erasing and re-inserting. For a more extensive discussion of this problem, check out Item 8 in “More Exceptional C++” by Herb Sutter.
It is perfectly safe to do a const_cast in this situation and it is not bad style, just make sure that you do not change the value of the fields that determine the order. If the interface of the class makes it hard to verify that you do not change the order, then the interface is probably not well designed.
c 容器中的对象是 const,smallObjectFunction 尝试修改对象值。
The object(s) in your c container are const and the smallObjectFunction tries to modify the object value.