当我使用迭代器时,我遇到了一些似乎是对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对象。这里有任何帮助或解释吗?
答案 0 :(得分:11)
根据排序条件设置和映射使元素按顺序排列。对于不破坏不变量的用户代码,映射的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!!!
现在的问题不仅是现在set元素不按顺序排列,而是根据树的构建方式,可能会有一些元素存在于集合中但无法找到。
答案 1 :(得分:3)
您的代码不愚蠢且可以使用符合标准的STL实现进行干净编译,具体取决于您的STL实现所做的一些设计决策。 C ++ 03 Standard没有为 set :: iterators 指定引用typedef 应该是什么(在我看来,它们应该是非常量引用)。所以继续做你做的,但插入 const_cast :
const_cast<SmallObject&>(*it).smallObjectFunction();
它比擦除和重新插入更有效,更清晰。有关此问题的更广泛讨论,请查看Herb Sutter撰写的“More Exceptional C ++”中的第8项。
在这种情况下进行 const_cast 是完全安全的,并且风格也不错,只需确保不要更改确定顺序的字段的值。如果类的接口使得很难验证您没有更改顺序,那么接口可能没有很好地设计。
答案 2 :(得分:0)
c容器中的对象是const,smallObjectFunction尝试修改对象值。