C ++,返回const和非const引用到std :: set item

时间:2012-01-24 22:31:29

标签: c++ reference set const

A类包含两个重载方法getItems();

typedef std::vector <int> TItems;

template <typename T>
class A 
{
private:
    T a;
    TItems items;

public:
    A(){}
    A ( const T a_, const TItems & items_) : a(a_) , items (items_) {}
    bool operator () ( const A <T> &aa ) {return a < aa.a;}
    TItems const & getItems() const {return items}
    TItems & getItems() {return items}
};

和A对象的集合

template <typename T>
struct TSet {typedef std::set <A <T> > Type;};

我想返回对TItems的const引用/引用,但只有第二种方法可以工作

int main ()
{
TSet <double> ::Type t;
TSet <double> ::Type::iterator it = t.begin();
t.insert (A <double>( 5, TItems(10,10)));

const TItems *items = &(it->getItems()); //OK
TItems *items = &(it->getItems()); //Error  
}

Error   1   error C2440: 'initializing' : cannot convert from 'const TItems *' to 'TItems *

是不是非常量引用能够修改A对象导致潜在重排的原因?但该组的项目不是由A.items安排的,而是由a。

安排的

有没有办法如何使用非常量引用修改A.items?

3 个答案:

答案 0 :(得分:2)

  

这是非常数引用能够修改A对象导致潜在重排的原因吗?

完全。 std::set的元素(和BTW std::map的键)是不可变的,结构只会给你const限定的元素。所以你有选择

  • 将您的结构更改为std::map,并将您的a作为关键字,items作为数据
  • 如果您完全确定不会通过items操纵来破坏排序,则const_cast可以items(或mutable {{1}}如果适合您)。

答案 1 :(得分:1)

如果允许更改set元素,则可能会破坏实现集合的结构的不变量(例如,平衡搜索树)。因此,集合的元素必须是不可变的。因此,如果要修改元素,则必须删除元素并将其替换为新元素。特别是,你不能指望通过迭代器到set的非const引用(如果你可以修改它,你可以打破顺序)。

答案 2 :(得分:0)

您无法更改存储在std :: set中的对象,因为这会破坏集合不变量。相反,您可以从集合中删除对象,然后修改它并再次插入。

另一种可能性是使用std :: map代替。地图的关键字无法修改,但值可以。