是否可以在容器中放置 std::array?如果是怎么样?如果不是,为什么?

Enr*_*lis 3 c++ c++11 stdarray emplace

鉴于简单的代码

#include <array>
#include <vector>
int main() {
    std::vector<std::array<int,3>> v;
    v.emplace_back(std::array<int,3>{1,2,3});
}
Run Code Online (Sandbox Code Playgroud)

我首先担心到底发生了什么。

我的理解emplace_back是,它通过将其参数转发到该元素的构造函数来就地构造一个元素(在本例中为std::array<int,3>具有值1, 2, 3)。

但是哪个构造函数?由于我们正在传递一个与我们想要放置的元素类型相同的对象,我猜选择了移动构造函数,因为我们正在传递一个临时构造函数,或者如果移动构造函数被删除(隐式或显式),则传递复制构造函数。此外,我们首先在构建那个临时的,而且没有到位,对吧?

因此,我们基本上调用“正常”(580)为构造器std::array<int,3>通过传递到它12以及3作为参数,从而取回一个临时的,被传递到复制构造函数的std::array<int,3>该代替构建拷贝,或优选到std::array<int,3>其中 (?) 复制底层 C 样式指针的移动 ctor ?

很明显,这个简单的例子让我很困惑。

更让我困惑的是,如果我真的想利用emplace_back,我只能将参数传递给std::array<int,3>,如

#include <array>
#include <vector>
int main() {
    std::vector<std::array<int,3>> v;
    v.emplace_back(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)

它甚至不编译。

Ser*_*eyA 5

让我试着澄清一下。首先,std::array<>是一个聚合。它根本没有任何用户定义的构造函数。

所以它是准可移动的(技术术语是微可移动的),这意味着你可以从临时构造它,但它只是简单地复制底层数组。所以代码最终做的是将提供的数组复制到新分配的向量元素中。

你会达到相同的结果(但会做略少打字)如果更换emplace_backpush_back类似如下:

    v.push_back({1,2,3});
Run Code Online (Sandbox Code Playgroud)

并且emplace_back(1, 2, 3)不会编译,因为std::array<>没有任何带有多个参数的构造函数。

  • @Enrico `std::array` 没有可窃取的指针,因为它不管理动态分配的内存。这是“std::array&lt;&gt;”和“std::vector&lt;&gt;”之间的主要区别。 (3认同)