使用带有显式构造函数的非可复制类型进行C ++ 11数组初始化

时间:2014-04-08 03:29:12

标签: c++ arrays c++11 initialization noncopyable

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

#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}'将使用显式构造函数   “的事情::事情(INT)”

好的,但这正是我想要的 - 使用显式构造函数。我该怎么表达呢?如果我自己实际调用构造函数,那么我会收到有关正在删除的复制构造函数的错误。我不能使用std::move()因为Thing不可移动(我无法修改它)。

我到目前为止找到的唯一替代方法是https://stackoverflow.com/a/15962814/4323,但这是不可取的,因为它是一堆额外的代码加上我需要在我使用它的地方投射“存储”(或者保留一个单独的指针) ,这增加了我不想要的间接。)

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

3 个答案:

答案 0 :(得分:1)

我尝试添加默认移动ctor和移动赋值运算符,稍微更改了初始化并编译:

#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
}
编辑:我错过了“第三方”部分。对不起,如果这没有用:)

答案 1 :(得分:1)

然而,C ++ 17的guaranteed copy elision再次受到拯救:像Thing{100}这样的表达式不再创建一个对象,而只是指定如何将创建一些其他对象(您的数组元素)。

答案 2 :(得分:-2)

您可以使用std::vector

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

或只有一个元素boost::optional

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