Ralph Tandetzky Ralph Tandetzky - 10 months ago 58
C++ Question

C++ container with non-copyable non-movable element type

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.

Is there an easy way to implement that without the overhead of memory allocation and indirection incurred by using


Answer Source

Here's a simple, yet incomplete solution under the assumption that each element is constructed with the same arguments:

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

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
  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)...);

    for (std::size_t i=0; i<m_sz; ++i)

  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:

  • 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.