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

Is it possible to emplace a std::array in a container? If it is how? If not, why?

给出简单的代码

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

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

我对emplace_back的理解是,它构造一个元素(在本例中是一个std::array<int,3>,值为123) -通过将其参数转发给该元素的构造函数来放置。

但是哪个构造器呢?因为我们正在传递一个与我们要放置的元素类型相同的对象,所以我猜选择了移动构造函数,因为我们正在传递一个临时构造函数,或者如果移动构造函数被删除(隐式或显式)则为复制构造函数。另外,我们首先是在构建那个临时的,那是不是就地完成的,对吧?

所以我们基本上是通过将 123 作为参数传递给 std::array<int,3> 来调用 std::array<int,3> 的“普通”(???) 构造函数,从而得到一个临时的,它被传递给 std::array<int,3> 的复制构造函数,它在适当的位置构造副本,或者最好是传递给 std::array<int,3> 的移动构造函数,它(?)复制底层的 C 风格指针?

应该清楚这个简单的例子让我很困惑。

更让我困惑的是,如果我真的想利用 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);
}

which doesn't even compile.

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

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

如果将 emplace_back 替换为 push_back,您将获得相同的结果(但打字会稍微少一些),如下所示:

    v.push_back({1,2,3});

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