[英]C++ , how to return a reference to the member variable from iterator
There is the following class B derived from std::vector 从std :: vector派生以下B类
class B: public std::vector <unsigned int>
{
public:
B() : std::vector <unsigned int> ( 0 ) {}
};
and a class A witten as follows: 和A级机智如下:
class A
{
private:
B b;
double x;
public:
B & getB () {return b;}
B const & getB() const {return b;}
bool operator() ( const A & a ) const
{
return a < a.x;
}
};
Why it is impossible to return a refererence to the variable b of some object A stored in std::list from its iterator (and how to do that)? 为什么不可能从其迭代器返回对存储在std :: list中的某个对象A的变量b的引用(以及如何做到这一点)?
int main ()
{
std::set <A > alist;
std::set <A> ::iterator i_alist = alist.begin();
for (; i_alist != alist.end(); i_list++)
{
B &il = (*i_alist).getB(); //Compiler error
B &il2 = i_alist->getB(); //Compiler error
il.push_back(10); //Modify il and concurrently B
}
}
Compiler error: 编译器错误:
Error 1 error C2440: 'initializing' : cannot convert from 'const B' to 'B &' d:\test.cpp
Thanks for your help... 谢谢你的帮助...
Edit question : 编辑问题 :
The possible solution using const_cast : 使用const_cast的可能解决方案:
B &il2 = const_cast <B&> ( i_alist->getB() );
This has very little to do with std::vector
and everything to do with std::set
. 这与
std::vector
几乎没有关系,而与std::set
无关。 You store your objects in a std::set
. 您将对象存储在
std::set
。 Elements of std::set
are not modifiable from the outside. std::set
元素不能从外部修改。 Once you inserted an element into a set, you cannot change it. 将元素插入集合后,就无法更改。
For this reason, std::set::iterator
might (and will) evaluate to a constant object, even if it is not a const_iterator
(the language specification actually allows std::set::iterator
and std::set::const_iterator
to refer to the same type, but does not require it). 因此,即使
std::set::iterator
不是const_iterator
(语言规范实际上允许std::set::iterator
和std::set::const_iterator
也可能),并且std::set::iterator
可能(并且将)评估为常量对象。以指代相同类型,但不需要)。 Ie in your example *i_list
is a const-qualified object of type const A
. 即在您的示例中
*i_list
是类型为const A
的const限定对象。 The compiler will call the const
version of getB
, which returns const B &
. 编译器将调用
getB
的const
版本,该版本返回const B &
。 You are apparently hoping to break through that constness, expecting the non-const version of getB
to be called. 您显然希望突破该常量,期望调用
getB
的非常量版本。
There's no way around it, unless you decide to use some sort of hack ( const_cast
etc.) to remove the constness from the set element and thus make the compiler to call non-const version of getB
. 除非您决定使用某种技巧(
const_cast
等)从set元素中删除constness并因此使编译器调用getB
非const版本, getB
。
The const_cast
-based hack-solution would look as 基于
const_cast
的黑客解决方案看起来像
B &il = const_cast<A &>(*i_alist).getB();
or you can remove the constness later, from the returned B
reference 或者您可以稍后从返回的
B
参考中删除常量。
B &il = const_cast<B &>((*i_alist).getB());
B &il2 = const_cast<B &>(i_alist->getB());
There are some things that look weird about your example: 关于您的示例,有些事情看起来很奇怪:
std::vector
. std::vector
派生。 It's not designed for that use. A::operator()
for? A::operator()
做什么用的? Looks like some strange way to provide a Comparator for the std::set
you are using. std::set
提供一个Comparator的某种奇怪方法。 Normally you don't alter a class just because you stuff it into a std::set
somewhere. std::set
某个类填充到std::set
而改变了一个类。 If you really want to be able to compare your A's (generally, not just for the set), then write a proper free bool operator<(A const&, A const&);
bool operator<(A const&, A const&);
If it's just for the set, write a custom Comparator in the place where you use the set. A::x
used for? A::x
是什么? Only for comparison or even only for the comparison inside the set? std::map<double, A>
or even a std::map<double, B>
where you put your x as the keys and the actual objects as the values. std::map<double, A>
或什至std::map<double, B>
,其中将x用作键,将实际对象用作值。 You see, there are a lot of open questions I ask, and maybe the solution (using a map) does not even fit your problem. 您会看到,我有很多未解决的问题,也许解决方案(使用地图)甚至不适合您的问题。 That is because you did not show us the real code you have but only some example with meaningless names.
那是因为您没有向我们展示您拥有的真实代码,而只是给我们展示了一些无意义的示例。 So we only see what you are trying to do , not what you actually want to achieve with your code.
因此,我们只看到您正在尝试执行的操作 ,而不是您实际上想要通过代码实现的操作。
PS: maybe you don't even need an ordered container in the first place, it could suffice to stuff all the objects into a std::vector
and then std::sort
it. PS:也许您甚至根本不需要一个有序的容器,将所有对象填充到
std::vector
然后std::sort
。 Depends on the kind of objects you really have (the A's of your example are cheap to copy/swap) and of the ways you use the container - how the insertions are interleaved with the loops and so on. 取决于您实际拥有的对象的种类(示例中的A很容易复制/交换)以及使用容器的方式-插入与循环的交错方式等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.