STL 迭代器和“const”

发布于 2024-09-12 00:09:19 字数 858 浏览 2 评论 0原文

当我使用迭代器时,我遇到了似乎对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尘曦 2024-09-19 00:09:19

集合和映射根据排序条件保持元素的顺序。为了使用户代码不破坏不变量,映射的 key 和集合中的整个元素必须是常量。您的问题是存储的元素不是 SmallObject 而是 const SmallObject

如果这不受限制,您可能会遇到:

int init[] = { 1, 2, 3, 4, 5 };
std::set<int> values( init, init+5 );
std::copy( values.begin(), values.end(), 
   std::ostream_iterator<int>(std::cout, " "));
   // 1 2 3 4 5
*(values.find(3)) = 5; // luckily this does not work!
std::copy( values.begin(), values.end(), 
   std::ostream_iterator<int>(std::cout, " "));
   // 1 2 5 4 5 -- not in order!!!

问题不仅在于现在集合元素不按顺序排列,而且取决于树的构建方式,可能存在集合中存在但无法找到的元素。

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 a SmallObject but a const SmallObject.

If this was not limited you could have:

int init[] = { 1, 2, 3, 4, 5 };
std::set<int> values( init, init+5 );
std::copy( values.begin(), values.end(), 
   std::ostream_iterator<int>(std::cout, " "));
   // 1 2 3 4 5
*(values.find(3)) = 5; // luckily this does not work!
std::copy( values.begin(), values.end(), 
   std::ostream_iterator<int>(std::cout, " "));
   // 1 2 5 4 5 -- not in order!!!

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.

阿楠 2024-09-19 00:09:19

您的代码愚蠢,并且可以使用一致的STL实现进行干净地编译,具体取决于您的STL实现所做的一些设计决策。 C++03 标准没有指定 set::iterators引用 typedef 应该是什么(在我看来,它们应该是非常量引用)。因此,继续做你所做的事情,但插入一个const_cast

const_cast<SmallObject&>(*it).smallObjectFunction();

它比擦除和重新插入更高效、更清晰。有关此问题的更广泛讨论,请查看 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:

const_cast<SmallObject&>(*it).smallObjectFunction();

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.

赏烟花じ飞满天 2024-09-19 00:09:19

c 容器中的对象是 const,smallObjectFunction 尝试修改对象值。

The object(s) in your c container are const and the smallObjectFunction tries to modify the object value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文