C ++,如何从迭代器返回对成员变量的引用

时间:2012-12-03 16:35:15

标签: c++ vector reference iterator set

从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() );

2 个答案:

答案 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(); 引用

中删除constness
B

答案 1 :(得分:0)

有些事情对你的例子看起来很奇怪:

  1. 永远不要来自std::vector。它不是为那种用途而设计的。通常没有理由这样做,除了懒惰,即避免一些打字。
  2. A::operator()是什么意思?看起来像是为您正在使用的std::set提供比较器的一种奇怪方式。通常,您不会因为将某个类填充到某个地方std::set而改变它。如果你真的希望能够比较你的A(通常不仅仅是设置),那么写一个合适的免费bool operator<(A const&, A const&);如果它只是为了集合,在你使用集合的地方写一个自定义比较器。 (那个比较器不应该需要访问A的私有)
  3. A::x用于什么?仅用于比较甚至仅用于集合内的比较?如果只是这样,请考虑使用std::map<double, A>甚至std::map<double, B>,其中您将x作为键,将实际对象作为值。
  4. 你知道,我问过很多未解决的问题,也许解决方案(使用地图)甚至不适合你的问题。那是因为你没有向我们展示你拥有的真正的代码,只有一些无名的例子。因此,我们只会看到您尝试的内容,而不是您实际想要实现代码的内容。

    PS:也许你甚至不需要一个有序的容器,只需将所有对象填充到std::vector然后std::sort就可以了。取决于你真正拥有的对象类型(你的例子的A是复制/交换便宜)以及你使用容器的方式 - 插入如何与循环交错等等。