[英]C++ , how to return a reference to the member variable from iterator
从std :: vector派生以下B类
class B: public std::vector <unsigned int>
{
public:
B() : std::vector <unsigned int> ( 0 ) {}
};
和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;
}
};
为什么不可能从其迭代器返回对存储在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
}
}
编译器错误:
Error 1 error C2440: 'initializing' : cannot convert from 'const B' to 'B &' d:\test.cpp
谢谢你的帮助...
编辑问题 :
使用const_cast的可能解决方案:
B &il2 = const_cast <B&> ( i_alist->getB() );
这与std::vector
几乎没有关系,而与std::set
无关。 您将对象存储在std::set
。 std::set
元素不能从外部修改。 将元素插入集合后,就无法更改。
因此,即使std::set::iterator
不是const_iterator
(语言规范实际上允许std::set::iterator
和std::set::const_iterator
也可能),并且std::set::iterator
可能(并且将)评估为常量对象。以指代相同类型,但不需要)。 即在您的示例中*i_list
是类型为const A
的const限定对象。 编译器将调用getB
的const
版本,该版本返回const B &
。 您显然希望突破该常量,期望调用getB
的非常量版本。
除非您决定使用某种技巧( const_cast
等)从set元素中删除constness并因此使编译器调用getB
非const版本, getB
。
基于const_cast
的黑客解决方案看起来像
B &il = const_cast<A &>(*i_alist).getB();
或者您可以稍后从返回的B
参考中删除常量。
B &il = const_cast<B &>((*i_alist).getB());
B &il2 = const_cast<B &>(i_alist->getB());
关于您的示例,有些事情看起来很奇怪:
std::vector
派生。 它不是为此设计的。 通常,除了懒惰以外,没有其他理由这样做,即避免打字。 A::operator()
做什么用的? 为您正在使用的std::set
提供一个Comparator的某种奇怪方法。 通常,您不会仅仅因为std::set
某个类填充到std::set
而改变了一个类。 如果您真的想比较A(通常不只是针对集合),则编写一个适当的免费bool operator<(A const&, A const&);
如果仅用于集合,请在使用集合的地方编写一个自定义比较器。 (该比较器不需要访问A的私有对象) A::x
是什么? 仅用于比较,甚至仅用于集合内的比较? 如果仅仅是这样,请考虑使用std::map<double, A>
或什至std::map<double, B>
,其中将x用作键,将实际对象用作值。 您会看到,我有很多未解决的问题,也许解决方案(使用地图)甚至不适合您的问题。 那是因为您没有向我们展示您拥有的真实代码,而只是给我们展示了一些无意义的示例。 因此,我们只看到您正在尝试执行的操作 ,而不是您实际上想要通过代码实现的操作。
PS:也许您甚至根本不需要一个有序的容器,将所有对象填充到std::vector
然后std::sort
。 取决于您实际拥有的对象的种类(示例中的A很容易复制/交换)以及使用容器的方式-插入与循环的交错方式等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.