如何返回 const std::vector

发布于 2024-10-07 21:20:23 字数 878 浏览 7 评论 0原文

我有一个以容器(包含指针)作为成员的类:

MyClass{
private:
   std::vector<MyObject*> _VecMyObjs;
public:
   const std::vector<MyObject* const> GetVecMyObj();
}

现在我尝试实现 GetVecMyObj()。这是我想到的......

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

但是编译器当然警告我,我在 const 对象上使用了分配函数。有更好的方法吗?我的意思是,我当然不希望 VecMyObjs 在类之外更改 VecMyObj。如何在没有编译器警告的情况下实现这一目标?

编辑: 好的。谢谢大家。现在是这样的:

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

但是,我无法绕过分配函数,对吧?例如,如果我希望“一切”保持不变,则铸造“原始”是行不通的。

I have a class with a container (containing pointer) as a member:

MyClass{
private:
   std::vector<MyObject*> _VecMyObjs;
public:
   const std::vector<MyObject* const> GetVecMyObj();
}

Now I try to implement GetVecMyObj(). Here is what I came up with...

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

But of course the compiler is warning me, that I use the assign-function on a const-Object. Is there a better way to do this? I mean, I don't want VecMyObjs to change VecMyObj outside of the class, of course. How can I achieve that without a compiler warning?

EDIT:
Okay. Thank you everybody. It's now like this:

const vector<MyObject *const> ACI_CALL MyClass::GetVecMyObjs()
{
   const vector<MyObject *const> VecMyObjs;
   VecMyObjs.assign( _VecMyObjs.begin(), _VecMyObjs.end());
   return VecMyObjs;
}

But, I can't get around the assign-function, right? E.g. casting the "original" doesn't work, if I want "everything" to be constant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一百个冬季 2024-10-14 21:20:23

我不确定 std::vector (常量指针向量)是否真的是您想要的:我相信您的意思是 std::vector (指向常量对象的指针向量)。

  1. 常量的“第一级”(指针常量)自然是通过返回向量上的常量引用来实现的。只有 const_iterator 可以从 const 向量中获取,因此您可以保证指针不会被修改(但pointees可以)。

  2. “第二级”常量(pointee常量)更难获得。要么返回一个新的向量实例,正如其他人已经指出的那样:

    return std::vector(_VecMyObjs.begin(), _VecMyObjs.end());
    

    或者,如果适用,请尝试查看 Boost Pointer Container 库(最值得注意的是 ptr_vector )它提供了正确的常量传播等功能:

    <块引用>

    传播常量,使得
    无法通过a修改对象
    常量迭代器。

您必须了解,返回向量上的 const 引用可以保证它不能被修改(不能插入、删除或修改其值)。因此,在大多数情况下,返回 const std::vector& 是正确的方法,因为 if 不涉及任何复制。这里的问题实际上是指针容器特有的,其中值的常量性并不提供被指针的常量性。

I'm not sure std::vector<MyObject * const> (vector of constant pointers) is really what you want : I believe you mean std::vector<MyObject const *> (vector of pointer to constant objects).

  1. The "first level" of constness (pointer constness) is naturally achieved by returning a constant reference on the vector. Only const_iterator can be obtained from a const vector, so you have a guarantee that the pointers won't be modified (but pointees can be).

  2. The "second level" of constness (pointee constness) is harder to obtain. Either return a new instance of a vector as already pointed out by others :

    return std::vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
    

    Or, if applicable, try to look into the Boost Pointer Container library (and most notably ptr_vector) which offers, among other things, correct constness propagation :

    Propagates constness such that one
    cannot modify the objects via a
    const_iterator.

You have to understand that returning a const reference on a vector guarantees that it cannot be modified (no insertion, deletion, or modification of its value). So, in most cases, returning a const std::vector<T> & is the way to go because if does not involve any copying. The issue here is really specific to container of pointers, where constness of the values does not provide constness of the pointees.

梦开始←不甜 2024-10-14 21:20:23

如果您想返回一个新的向量,请勿将其设置为const。将 const 关键字放在 * 之前。

std::vector<MyObject const*> MyClass::GetVecMyObj()
{
    return std::vector<MyObject const*>(_VecMyObjs.begin(), _VecMyObjs.end());
}

我省略了到 TRoadSgmt 的转换,因为您没有指定此类的继承。

If you want to return a fresh vector, don't make it const. Put the const keyword before the *.

std::vector<MyObject const*> MyClass::GetVecMyObj()
{
    return std::vector<MyObject const*>(_VecMyObjs.begin(), _VecMyObjs.end());
}

I omitted the conversion to TRoadSgmt as you didn't specify the inheritance of this class.

≈。彩虹 2024-10-14 21:20:23

假设非常量指针的向量在整个生命周期中驻留在某个地方,您将使用 const 版本,因此您不需要副本,并且如果有很多指针,则您不想复制向量,你最好返回某种定制的包装对象,只为用户提供 const 访问权限。

向量的第一个元素的地址将是 T** 并且您不能将其转换为 const T** (正确),也不能将其转换为 const T*const * (这将是安全的,但语言不允许)。

如果您被允许转换后者,那么它将非常适合创建只读视图。

Assuming the vector of the non-const pointers resides somewhere during the entire lifetime that you are going to use the const-version so you don't need a copy, and if there a lot of them so you don't want to copy the vector, you are better off returning some kind of wrapper object that is custom made to only give the user const-access.

The address of the first element of the vector will be T** and you can't cast that to const T** (correctly) nor can you cast it to const T*const * (which would be safe but the language does not allow it).

If you were allowed to convert the latter it would be perfect for creating a read-only view.

温柔嚣张 2024-10-14 21:20:23

除了更改签名以从向量中删除const(因为它是向量的副本)之外,我假设您不希望外部的人修改结果,内容生成一个 const 指针,即

vector<const MyObject *> ACI_CALL MyClass::GetVecMyObjs()
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

现在返回的向量是一个副本,其中包含 const 指针(这意味着您无法通过此指针修改指向的对象) - 好吧,那就是根据协议,没有什么可以阻止某人通过 const_cast 删除它(无论如何使用它都是 UB!)

如果您确实想防止修改,请在向量中返回一个副本(或每个对象的克隆)。

Aside from changing the signature to remove the const from the vector (as it's a copy of the vector), I'm assuming that you don't want people outside to modify the contents, as a result, make a const pointer , i.e.

vector<const MyObject *> ACI_CALL MyClass::GetVecMyObjs()
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

Now the returned vector is a copy, which contain const pointer (which means you can't modify the pointed object via this pointer) - well that's the agreement, there's nothing preventing someone from const_casting that away (using that is UB anyways!)

If you really want to prevent modifications, return a copy (or clone of each object) in the vector.

_畞蕅 2024-10-14 21:20:23
const vector<const MyObject *> MyClass::GetVecMyObjs() const
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

这对我来说似乎是解决方案。感谢我收到的所有不同的帖子,我现在可以知道了。
谢谢大家!祝你过得愉快...
(或者如果我仍然在某个地方错了,请告诉我。)

const vector<const MyObject *> MyClass::GetVecMyObjs() const
{
   return vector<const MyObject *>(_VecMyObjs.begin(), _VecMyObjs.end());
}

This seems to be the solution to me. I can tell now, thanks to all the different posts I got.
Thanks all of you! Have a nice one...
(Or let me know, if I am still wrong somewhere.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文