C++,返回对 std::set 项的 const 和非 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;};
我想返回 const 引用/对 TItems 的引用,但只有第二种方法有效,
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.items 排列的。
有没有办法使用非常量引用来修改 A.items?
There is the class A containing two overloaded methods 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}
};
and the set of A objects
template <typename T>
struct TSet {typedef std::set <A <T> > Type;};
I would like to return const reference / reference to TItems, but only the second method works
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 *
Is it the reason that non-constant references enables to modify A objects causing a potential rearrangement od the set? But items of the set are not arranged by A.items but by a.
Is there a way how modify A.items using a non-constant reference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确切地。
std::set
的元素(以及顺便说一句std::map
的键)是不可变的,该结构只会为您提供 const 限定的元素。 您可以选择items
操作来破坏排序,您可以const_cast
(或者声明items
mutable
如果适合的话你)。Exactly.
std::set
's elements (and BTWstd::map
's keys) are immutable, the structure will only give you const-qualified elements. So you have the optionstd::map
and put youra
as key anditems
as dataitems
, you canconst_cast
(or declareitems
mutable
if that suits you).如果允许更改集合元素,则可能会破坏实现集合的结构的不变量(例如平衡搜索树)。因此,集合的元素必须是不可变的。因此,如果要修改某个元素,则必须删除某个元素并用新元素替换它。特别是,您不能期望通过迭代器来设置非常量引用(如果您可以修改它,则可能会破坏顺序)。
。
If you are allowed to change set elements, you may break the invariants of the structure implementing the set (eg. balanced search tree). Elements of sets must thus be immutable. So you must remove an element and replace it with a new one if you want to modify an element. In particular, you cannot expect a non-const reference through an iterator to
set
(if you could modify it, you could break the ordering)..
您无法更改存储在 std::set 中的对象,因为这会破坏集合不变量。相反,您可以从集合中删除该对象,然后修改它并再次插入。
另一种可能性是使用 std::map 代替。映射的键不能修改,但值可以。
You can not change the objects stored in a std::set because this would break the set invariants. Instead you could remove the object from the set then modify it and insert it again.
An other possibility is to use a std::map instead. The key of the map cannot be modified but the value can.