0

I have a circular buffer class whose constructor is:

template <class T>
class circular_buffer {
public:
    circular_buffer(size_t size) :
    buf(std::unique_ptr<T[]>(new T[size])),
    max_size(size)
{}

I want to create a std::array of these circular buffers. So I need a declaration that is something like:

std::array< circular_buffer<TMyType>, MAX_BUFFERS > bufferArray;

But that fails with error:

function was implicitly deleted because a data member 'std::array<circular_buffer<TMyType>,14>::_Elems' has either no appropriate default constructor or overload resolution was ambiguous

The reason seems obvious that I am providing no parameter for circular_buffer's constructor ('size').

How would I correct the declaration of bufferArray to specify 'size'?

DavidA
  • 2,053
  • 6
  • 30
  • 54
  • Since you use a pointer to heap memory, why not just a `std::vector`? – Alexey S. Larionov Oct 04 '21 at 17:04
  • @alexey-larionov The number of buffers is constant so an array seems more natural. Also, I need the code to be very fast and array may be faster than vector? – DavidA Oct 04 '21 at 17:09
  • You can provide a default constructor for `circular_buffer`, and re-assign the value after creating the empty `array`. [demo](https://godbolt.org/z/va5n4rhdT) – 康桓瑋 Oct 04 '21 at 17:14
  • *Also, I need the code to be very fast and array may be faster than vector?* Faster to use? No. Faster to create? No. Faster to destroy? No. Exist entirely on the stack? Yes, a C style can do that; but you're not leveraging that capability here. Not have any reallocations? A `std::vector` can have its capacity reserved. Not be dynamic and has a fixed size? A `std::vector` can be resized to a fixed size. – Eljay Oct 04 '21 at 17:21
  • The "performance" here falls down to how fast you can access an element. In your case assuming you have some `circular_buffer cb;`, then to access an element you need to dereference the unique pointer and access an offset of this address. If you had a vector instead of the unique pointer, then you'd have to dereference pointer inside the vector and access an offset of this address. In short - I expect exactly the same performance – Alexey S. Larionov Oct 04 '21 at 17:21
  • 1
    I think you may be able to adapt this answer: https://stackoverflow.com/a/41259045/742314 to solve your problem. – idz Oct 04 '21 at 17:27
  • Thank you all for your helpful answers. I will relent and use a vector. – DavidA Oct 04 '21 at 17:42
  • So, how would I instantiate a vector and specify the 'size' constructor parameter? This is obviously wrong: std::vector< circular_buffer > ringVec(size); – DavidA Oct 04 '21 at 17:59
  • 1
    @DavidA: Pass the desired size and an example item to be copied. It's constructor #3 here: https://en.cppreference.com/w/cpp/container/vector/vector So: `std::vector> ringVec(MAX_BUFFERS, circular_buffer(size));` – Ben Voigt Oct 04 '21 at 19:33

0 Answers0