cast stl :: vector包含指向包含常量指针的stl :: vector的指针

时间:2011-09-14 08:37:29

标签: c++ templates casting const

考虑以下课程:

class SomeInfo
{
private:
    std::vector<someObj *> _myVector;

public:
    const std::vector<const someObj*>& getInfoVector() const
    {
        return _myVector;
    }
};

当我尝试使用gcc 4.1.2编译时,它给出了以下错误:

error: invalid initialization of reference of type 
‘const std::vector<const someObj*, std::allocator<const someObj*> >&’ 
from expression of type 
‘const std::vector<someObj*, std::allocator<someObj*> >

如果我删除'someObj *'前面的'const',那么它会编译,但我不想返回带有非常量指针的向量,因为我不希望它们引用的对象是从我的SomeInfo类外部改变。在这种情况下你会做什么?

4 个答案:

答案 0 :(得分:3)

在这种情况下我会做的是忘记返回vector(或引用它)。调用者无法进行任何更改,因此无需查看任何特定容器。其他答案解释了为什么你不能将你的向量称为const someObj*的向量。就此而言,如果您将来更改班级以使用deque而不是vector,则无法返回对该类的引用,就好像它也是向量一样。由于调用者只需要访问元素,让我们给他们:

const someObj *getInfoAt(size_t n) const {
    return _myVector.at(n);
}

const_info_iterator getInfoBegin() const {
    return _myVector.begin();
}

const_info_iterator getInfoEnd() const {
    return _myVector.end();
}

size_t getInfoSize() const {
    return _myVector.size();
}

// plus anything else they need.

const_info_iterator是一个类的typedef,它写起来有些烦人。它必须包含std::vector<someObj *>::const_iterator和const-ify operator*的类型。 boost::transform_iterator可能有用,或者从头开始编写并不是那么糟糕。但是,双向迭代器确实需要大多数操作符重载。

现在,如果调用者确实需要const someObj*的向量,那么使用我的界面他们可以在任何特定时刻轻松获取快照:

std::vector<const someObj*> mycopy(myinfo.getInfoBegin(), myinfo.getInfoEnd());

他们所不能拥有的是vector,它会不断反映其他地方某些其他类型的vector所做的更改 - std::vector只是不这样做。 / p>

答案 1 :(得分:0)

std::vector<T*>std::vector<const T*>的类型不同。你怎么写这个:

std::vector<T*> obj(100);
std::vector<const T*> & ref = obj; //error

这是你在代码中所做的,这是无效的。您可以引用一种类型,以引用其他类型的对象。

所以试试这个:

std::vector<const someObj*> getInfoVector() const
{
    return std::vector<const someObj*>(_myVector.begin(), _myVector.end());
}

现在它正在返回一个临时向量,其中包含原始向量中的指针。另请注意,返回类型不再是 引用

答案 2 :(得分:0)

你可以写这样的getInfoVector:

std::vector<const someObj*> getInfoVector() const
{
  std::vector<const someObj*> obj;
  std::copy( _myVector.begin(), _myVector.end(), std::back_inserter( obj ) );
  return obj;
}

答案 3 :(得分:0)

  

在这种情况下你会做什么?

作为其他答案的替代方案,这是一个简单的方法,不需要复制或分配:

const someObj* SomeInfo::getSomeObjAt(const size_t& idx) const {
  return this->_myVector.at(idx);
}

在许多情况下甚至更好,只是让SomeInfo 暴露其内部。