从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() );
答案 0 :(得分:7)
这与std::vector
几乎没有关系,而与std::set
有关。您将对象存储在std::set
中。 std::set
的元素不能从外部修改。将元素插入集合后,无法更改它。
出于这个原因,std::set::iterator
可能(并将会)评估为常量对象,即使它不是const_iterator
(语言规范实际允许std::set::iterator
和{{1} }引用相同的类型,但不要求它)。即在您的示例中,std::set::const_iterator
是*i_list
类型的const限定对象。编译器将调用const A
const
版本的getB
,返回const B &
。您显然希望突破该constness,期望调用{const} getB
的非const版本。
除非你决定使用某种hack(const_cast
等)从set元素中删除constness,从而使编译器调用{{1的非const版本,否则无法绕过它}}
基于getB
的黑客解决方案看起来像
const_cast
或者您可以稍后从返回的B &il = const_cast<A &>(*i_alist).getB();
引用
B
答案 1 :(得分:0)
有些事情对你的例子看起来很奇怪:
std::vector
。它不是为那种用途而设计的。通常没有理由这样做,除了懒惰,即避免一些打字。A::operator()
是什么意思?看起来像是为您正在使用的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是复制/交换便宜)以及你使用容器的方式 - 插入如何与循环交错等等。