安放 std::array 个无法默认构造的不可移动物体

Emplace a std::array of non-movable objects that cannot be default constructed

我有一个 class,其中包含一个 std::mutex,因此它不可移动或复制。

struct MyObject {
  MyObject(std::string s_) : s(s_) {};
  std::mutex lock;
  std::thread worker;
  std::string s;
};

我可以轻松地将此对象添加到此地图中:

 std::map<int, MyObject> my_map;
 my_map.emplace(std::piecewise_construct, 
                std::forward_as_tuple(5),
                std::forward_as_tuple("string0"));

但我想用一个 std::array 来容纳其中的几个,例如:

std::map<int, std::array<MyObject, 3>> my_map;

如果MyObject是可移动的,那么我可以这样做:

my_map.emplace(4, {MyObject("string0"), MyObject("string1"), MyObject("string2")});

但是当 MyObject 不可移动时这不起作用(正如预期的那样)。我不能回到分段构造,因为 std::array 不能由 3 个字符串的元组构造。

 my_map.emplace(std::piecewise_construct, 
                std::forward_as_tuple(4),
                std::forward_as_tuple("string0", "string1", "string2"));

有没有办法在地图中就地构建 std::array 个不可移动的对象?

我将这些问题用作参考。有没有办法合并答案?

emplace and unordered_map<?, std::array<?, N>>

How to allocate a non-copyable and non-movable object into std::map?

我也试过:

std::array<MyObject, 3> list = {
  MyObject("string0"),
  MyObject("string1"),
  MyObject("string2")
};

my_map.emplace(4, std::move(list));

想法列表应该是可移动的,但这也行不通。

使用自定义数组,您可能会这样做

template <typename T, std::size_t N>
struct MyArray
{
    template <typename... Us>
    MyArray(Us&&... args) : arr{ std::forward<Us>(args)...} {}

    std::array<T, N> arr;
};

void foo()
{
    std::map<int, MyArray<MyObject, 3>> my_map;
    my_map.emplace(std::piecewise_construct,
                   std::forward_as_tuple(4),
                   std::forward_as_tuple(std::string("string0"),
                                         std::string("string1"),
                                         std::string("string2")));
}

Demo