在构造函数的初始化列表中初始化一个std::unique_ptr的std::array是否可行?

3
我想到了以下类型的代码:

class Surface { /* abstract base class with various properly derived classes */ };

struct ParallelSurfaces
{
    std::array<std::unique_ptr<Surface>, 2> surfacePtrs;

    ParallelSurfaces()
    : surfacePtrs({std::unique_ptr<Surface>(), std::unique_ptr<Surface>()})
    { }
};

然而,这并不起作用,因为unique_ptr的复制构造函数被删除了。(Visual Studio 2013报告错误 C2280: 'std::unique_ptr<Surface,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function)

  • 在初始化列表中是否有可能实现?

  • 还是必须在构造函数体中实现?

  • 或者我可以只让它默认初始化?(因为我只想在构建时存储nullptr以稍后重置它们)


你得到了什么编译器错误?我认为这应该没问题,因为将使用移动构造函数。 - TartanLlama
4
这里没问题。顺便说一下,std::array将被默认初始化,所以您不需要这样做。 - songyuanyao
哪个版本的VS? - Simon Kraemer
嘿,编译错误出现在Visual Studio 2013上。我已经将此添加到问题详情中。 - mr_T
2
如果你想要空指针(nullptr),只需省略初始化即可。unique_ptr u会被初始化为空,就像你将 nullptr 分配给它一样。你可以通过转换为 bool 来测试是否填充了它,例如if(u) { /*...已填充...*/ } - davidhigh
1个回答

4
长话短说,这实际上是标准库中一个相当令人讨厌的案例,如果我没记错的话,在C++14中已得到解决。所以这不是编译器错误,但应该在新的编译器中得到修复。
在这种情况下最简单的做法是只需放弃初始化,因为数组的默认初始化将生成您想要的值。

我认为这里默认初始化的不是数组,而是unique_ptr。如果它是一个std::array<int,2>,那么在放弃初始化后,它将包含任意值。 - davidhigh
1
数组的默认初始化做了我们想要的事情,即默认初始化unique_ptrs。 - Puppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接