Initializing an array of objects without an operator =, copy constructor or default constructor and run-time arguments

Renouncement

I am trying to allocate an array of objects that are not constructive for copying, are assigned and do not have a default constructor. Objects have arguments that are determined at runtime. I know that you can solve this problem by having an array of pointers or skillfully using a new placement, but I'm more interested if this can be done using the magic of C ++ 11 (1y). So, please, this is a purely theoretical interest, so do not try to solve "my problem" by offering a job.

The code...

... So the question is: is there a way to do the following work in C ++ 11 or C ++ 14:

class X{
public:
  explicit X(int a){...}
  X(const X&) = delete;
  void operator = (const X&) = delete;
private:
  ...
};

class Y{
public:
  Y(const std::vector<int>& args) {
    x = new X[]{args};
  }
  ~Y(){
    delete [] x;
  }
private:
  X* x;
};

Criteria

, /, :

  • X .
  • X .
  • X ( ).
  • X .
  • X .
  • X , ( , ). .

/

, . X this , .

+3
3

, , , , ( ) ( ).

, . .

template <typename T>
class fixed_capacity_vector {
public:
  using size_type = std::size_t;

  fixed_capacity_vector(size_type capacity)
    : data_(::operator new(capacity * sizeof(T)), size_(), capacity_(capacity)
  {}

  fixed_capacity_vector(const fixed_capacity_vector&) = delete;
  fixed_capacity_vector(fixed_capacity_vector&&) = delete;
  fixed_capacity_vector& operator =(const fixed_capacity_vector&) = delete;
  fixed_capacity_vector& operator =(fixed_capacity_vector&&) = delete;

  ~fixed_capacity_vector() {
    for (size_type i = 0; i < size_; ++i) data_[i].~T();
    ::operator delete(data_);
  }

  template <typename... Args>
  T& emplace_back(Args&&... args) {
    if (size_ == capacity_) throw out_of_range();
    new (data_ + size_) T(std::forward<Args>(args)...);
    ++size_;
    return data_[size_-1];
  }

private:
  T* data_;
  size_type size_;
  size_type capacity_;
};
+3

std::vector emplace_back, X .

class X{
public:
  explicit X(int){}
  X(X&&) = default;
  X(const X&) = delete;
  void operator = (const X&) = delete;
};

int main() {
    std::vector<X> xs;
    xs.emplace_back(0);
    xs.emplace_back(1);
    xs.emplace_back(2);
    xs.emplace_back(3);
}

( , , - , )

"array with placement new", .

, , . .

+4

, allocator, :

class Y{
public:
  Y(const std::vector<int>& args):
    alloc{},
    n{args.size()},
    x{alloc.allocate(n)}
  {
    auto end = x;
    try {
      for (auto arg: args)
        alloc.construct(end++, arg);
    } catch (...) {
      while (end != x)
        alloc.destroy(--end);
      alloc.deallocate(x, n);
      throw;
    }
  }
  ~Y() {
    for (auto end = std::next(x, n); end != x; --end)
      alloc.destroy(end);
    alloc.deallocate(x, n);
  }
private:
  std::allocator<X> alloc;
  const std::size_t n;
  const X *x;
};
+4

All Articles