具有不可复制的不可移动元素类型的C ++容器 [英] C++ container with non-copyable non-movable element type

查看:93
本文介绍了具有不可复制的不可移动元素类型的C ++容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个既不可复制也不可移动的元素容器。这些元素不是默认可构造的,但是它们的构造函数具有相同的参数。

I need a container of elements that are neither copyable nor movable. These elements are not default constructible, but their constructors get identical arguments.

容器的寿命不会改变。它应该像内置数组一样简单,但是它的大小是在运行时调用构造函数时确定的。

The size of the container does not change during it's lifetime. It should be as simple as a built-in array, but it's size is determined at run-time when the constructor is called.

有没有一种简单的方法可以实现这一点,而不会导致使用 std :: vector< std :: unique_ptr<引起的内存分配和间接开销。 T>>

Is there an easy way to implement that without the overhead of memory allocation and indirection incurred by using std::vector<std::unique_ptr<T>>?

推荐答案

在每个元素都假定的情况下,这是一个简单但不完整的解决方案用相同的参数构造。它使用展示位置 来构造就地元素(另请参见此SO问题):

Here's a simple, yet incomplete solution under the assumption that each element is constructed with the same arguments. It uses placement new to construct the elements in-place (see also this SO question):

#include <cstdlib>
#include <utility>
#include <new>

// sample structure, non-copyable, non-moveable, non-default-constructible
struct Foo
{
  Foo() = delete;
  Foo(const Foo&) = delete;
  Foo& operator = (const Foo&) = delete;
  Foo(Foo&&) = delete;
  Foo& operator = (Foo&&) = delete;

  Foo(int a, char b, double c) : m_a(a), m_b(b), m_c(c) { }

  int m_a;
  char m_b;
  double m_c;
};

template <typename T>
struct MyArray
{
  // Array ctor constructs all elements in-place using the
  // provided parameters
  template <typename... Args>
  MyArray(std::size_t sz, Args&&... args)
    : m_sz(sz),
      m_data(static_cast<T*>(malloc(sz * sizeof(T))))
  {
    for (std::size_t i=0; i<m_sz; ++i)
    {
      new (&m_data[i]) T(std::forward<Args>(args)...);
    }
  }

  ~MyArray()
  {
    for (std::size_t i=0; i<m_sz; ++i)
    {
      m_data[i].~T();
    }
    free(m_data);
  }

  std::size_t m_sz;
  T *m_data;
};

int main()
{
  Foo foo(1, '2', 3.0);
  std::size_t s = 5;
  MyArray<Foo> foo_arr(s, 1, '2', 3.0);
}

请注意,缺少一些内容:

Note that a few things are missing:


  • 如果在 MyArray 的构造函数中引发异常,此基本实现将泄漏内存。

  • 您可能需要迭代器实现, begin() / end()运算符等,

  • 出于说明的目的,我也没有为适当的封装而烦恼。您应该将 m_sz m_data 设为私有成员。

  • This basic implementation will leak memory if an exception is thrown inside MyArray's constructor.
  • You will probably want an iterator implementation, begin()/end() operators etc., for more convenience and to get the same behaviour as provided by the standard containers.
  • For illustration's sake I also didn't bother with proper encapsulation. You should probably make m_sz and m_data private members.

这篇关于具有不可复制的不可移动元素类型的C ++容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆