STL迭代器和'const'

时间:2010-07-28 15:16:37

标签: c++ iterator 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对象。这里有任何帮助或解释吗?

3 个答案:

答案 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尝试修改对象值。