如何将 unique_ptr 的向量声明为类数据成员?

发布于 2024-12-28 11:34:59 字数 710 浏览 5 评论 0原文

我想要一个 unique_ptr 的向量作为我正在创建的类的成员。

class Foo {
    [...]

private:
    vector<unique_ptr<Bar>> barList;
}

但随后我开始从 VS2010 编译器收到神秘的错误消息:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

以及下面的一些错误行,这些错误行深入探讨了 Microsoft 的 std::_Copy_impl<> 实现。 ..

我将成员声明更改为

vector<unique_ptr<Bar>>* barList;

并且它可以编译。但我不禁想,为什么我不能按照自己原本想要的方式去做呢?为了一笑,我尝试了这个,效果很好:

vector<Bar> barList;

但现在我失去了 unique_ptr 的便利。我想要我的蛋糕,我也想吃它!

I'd like to have a vector of unique_ptr's as a member of a class I'm making.

class Foo {
    [...]

private:
    vector<unique_ptr<Bar>> barList;
}

But then I start getting cryptic error messages from the VS2010 compiler:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

Along with a handful of error lines below that which dive into Microsoft's implementation of std::_Copy_impl<>...

I changed the member declaration to

vector<unique_ptr<Bar>>* barList;

And it compiles. But I can't help but wonder why I can't do it the way I originally wanted? For grins, I tried this and it works fine:

vector<Bar> barList;

But now I lose the convenience of unique_ptr. I want my cake and I want to eat it too!

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

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

发布评论

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

评论(6

少年亿悲伤 2025-01-04 11:34:59

这里的问题是,您的代码在某个地方尝试调用 Foo 的“复制赋值”运算符。

这会导致编译器尝试生成一个复制赋值运算符,该运算符调用 Foo 所有子对象的复制赋值运算符。最终,这会导致尝试复制unique_ptr,这是不可能的操作。

The problem here is that somewhere, your code is attempting to call the "copy-assignment" operator of Foo.

This causes the compiler to attempt to generate a copy-assignment operator which calls the copy-assignment operators of all the subobjects of Foo. Eventually, this leads to an attempt to copy a unique_ptr, an operation which is not possible.

不爱素颜 2025-01-04 11:34:59

unique_ptr 没有复制语义,因此您不能使用任何复制所包含对象的方法。您可以通过在尝试复制的位置使用std::move来使用右值引用来完成此操作。如果没有看到你的代码,我无法说出那会在哪里。

如果它以第二种形式编译,要么您没有执行相同的代码,要么存在编译器错误。两者都应该以同样的方式失败。

第三个示例,按值存储是最简单的方法,除非您的对象很大且按值存储/复制成本高昂。

unique_ptr doesn't have copy semantics, so you can't use any methods that would copy the contained object. You can do this with rvalue references by using std::move in the place(s) it's trying to make a copy. Without seeing your code I can't say where that would be.

If it compiles in the second form either you didn't exercise the same code or there's a compiler bug. Both should fail the same way.

Your third example, storing by value is the simplest way unless your objects are large and expensive to store/copy around by value.

可爱暴击 2025-01-04 11:34:59

通常,std::move(iUniquePtr) 会在某处丢失(例如,当使用push_back 时)。

Often a std::move(iUniquePtr) is missing somewhere (e. g. when using push_back).

倾`听者〃 2025-01-04 11:34:59

常见的问题是erase()emplace*()push*()。这些将尝试移动向量元素,因为其中一个或多个向量元素被删除或插入。虽然这应该可行,因为 std::unique_ptr 是可移动的,并且移位并不是严格要求的,但有时却不能,原因是 STL 实现中的错误。因此,您可能最好使用 std::list ,使用 std::shared_ptrs,使用 std::vector 替代方案、提交错误或仅使用原始指针,这是一个非常简单且有效的解决方案。

The usual problems are erase(), emplace*() and push*(). These will try to shift vector elements around, as one or more than one of them are erased or inserted. While this should work, as std::unique_ptr is movable and shifting is not strictly required, it sometimes does not and the reason are bugs in STL implementations. You may be better off with a std::list for this reason, use std::shared_ptrs, use a std::vector alternative, file a bug, or just use raw pointers, a surprisingly easy and effective solution.

红ご颜醉 2025-01-04 11:34:59

摘自 www.cplusplus.com

std::unique_ptr::operator=

unique_ptr 赋值
该对象获取 x 内容的所有权,包括存储的指针和存储的删除器(以及在某个时刻删除该对象的责任)。在调用之前,unique_ptr 对象所拥有的任何对象都将被删除(就像调用了 unique_ptr 的析构函数一样)。

但是也有一个警告:

此页面描述了最新版本的 C++ 标准引入的一项功能( 2011)。较旧的编译器可能不支持它。

MSVC 2010 将 operator= 定义为私有(不可复制),但支持 swap 方法。

An excerpts from www.cplusplus.com

std::unique_ptr::operator=

unique_ptr assignment
The object acquires the ownership of x's content, including both the stored pointer and the stored deleter (along with the responsibility of deleting the object at some point). Any object owned by the unique_ptr object before the call is deleted (as if unique_ptr's destructor was called).

But there is a warning too:

This page describes a feature introduced by the latest revision of the C++ standard (2011). Older compilers may not support it.

MSVC 2010 defines operator= as private (non-copyable) but supports swap method.

浪荡不羁 2025-01-04 11:34:59

您不能在向量中使用 unique_ptr,因为向量实现强烈依赖于值分配运算符,而该运算符在 unique_ptr 中是私有的。使用 boost 中的 shared_ptr 或 C++11 中的其他智能 ptr 实现。

You can't use unique_ptr in vector because vector implementation strongly relies on values assign operator, which is private in unique_ptr. Use shared_ptr from boost or other smart ptr implementation from C++11.

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