1

有以下 B 类派生自 std::vector

class B: public std::vector <unsigned int>
{
    public:
            B() : std::vector <unsigned int> ( 0 ) {}
};

和一个 A 类 witten 如下:

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

2 回答 2

7

这与 . 几乎没有关系,std::vector而与std::set. 您将对象存储在std::set. 的元素std::set不能从外部修改。一旦将元素插入到集合中,就无法更改它。

出于这个原因,std::set::iterator可能(并且将)评估为一个常量对象,即使它不是一个const_iterator(语言规范实际上允许std::set::iteratorstd::set::const_iterator引用相同的类型,但不需要它)。即在您的示例*i_list中是 const 限定的 type 对象const A。编译器将调用 的const版本getB,该版本返回const B &。您显然希望突破这种 constness,期望getB调用非 const 版本。

没有办法解决它,除非您决定使用某种 hack(const_cast等)从 set 元素中删除 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());
于 2012-12-03T16:39:01.737 回答
0

您的示例有些地方看起来很奇怪:

  1. 永远不要从std::vector. 它不是为这种用途而设计的。通常没有理由这样做,除了懒惰,即避免一些打字。
  2. 那是A::operator()为了什么?看起来像一些奇怪的方式来为std::set你正在使用的提供一个比较器。通常你不会因为你把它塞进std::set某个地方而改变一个类。如果您真的希望能够比较您的A(通常,不仅仅是为了集合),然后编写一个适当的免费bool operator<(A const&, A const&);如果它只是为了集合,请在您使用集合的地方编写一个自定义比较器。(该比较器不应该需要访问 A 的私人信息)
  3. 是干什么A::x用的?仅用于比较还是仅用于集合内的比较?如果只是这样,请考虑使用 astd::map<double, A>甚至 astd::map<double, B>您将 x 作为键和实际对象作为值的位置。

你看,我问了很多悬而未决的问题,也许解决方案(使用地图)甚至不适合你的问题。那是因为您没有向我们展示您拥有的真实代码,而只是向我们展示了一些名称毫无意义的示例。所以我们只看到你想要的事情,而不是你真正想用你的代码实现的目标。

PS:也许你甚至不需要一个有序的容器,将所有对象都塞进 astd::vector然后std::sort它就足够了。取决于您真正拥有的对象类型(您的示例中的 A 复制/交换很便宜)以及您使用容器的方式 - 插入如何与循环交错等等。

于 2012-12-03T17:01:47.917 回答