带有显式构造函数的不可复制类型的C++11数组初始化

C++11 array initialization with a non-copyable type with explicit constructor

本文关键字:类型 C++11 数组 初始化 可复制 构造函数      更新时间:2023-10-16

我有一个(第三方)类,它是不可复制的。我想初始化它们的数组。这是我最好的尝试:

#include <array>
class Thing
{
public:
  explicit Thing(int) {}
  Thing(const Thing&) = delete;
};
int main()
{
  std::array<Thing, 1> things{{{100}}}; // error here
};

GCC 4.7.2规定:

错误:转换为'std::array::value_type初始化项列表中的"{aka Thing}"将使用显式构造函数'Thing::Thing(int)'

好吧,但这正是我想要的——使用显式构造函数。我该怎么表达呢?如果我真的自己调用了构造函数,那么我会得到一个关于复制构造函数被删除的错误。我不能使用std::move(),因为Thing是不可移动的(我不能修改它)。

到目前为止,我找到的唯一选择是https://stackoverflow.com/a/15962814/4323但这是不可取的,因为这是一堆额外的代码,而且我需要在使用它的任何地方强制转换"存储"(或者保留一个指向它的单独指针,这会增加我不想要的间接性)。

我想要一个在实际使用Things时提供最大性能的解决方案,而不需要太多丑陋的样板。

再一次,C++17的保证拷贝省略起到了拯救作用:像Thing{100}这样的表达式不再创建对象,而只是指定如何创建其他对象(数组元素)。

我尝试添加默认的move ctor和move assignment操作符,稍微更改了初始化,它编译为:

#include <array>
class Thing
{
public:
  explicit Thing(int) {}
  Thing(const Thing&) = delete;
  Thing(Thing&&) = default;
  Thing& operator=(Thing&&) = default;
};
int main()
{
    std::array<Thing, 1> things {{ Thing(100) }}; // error gone
}

编辑:我错过了"第三方"的部分。很抱歉,如果这没有帮助:)

您可以使用std::vector:

std::vector<Thing> things;
things.reserve(1);
things.emplace_back(100);

或者仅针对一个元素boost::optional:

boost::optional<Thing> thing;
thing.emplace(100);