Rajiv
Rajiv

Reputation: 2649

What is the recommended way to have an inline array member of dynamic size?

I want a class with an inline array (Not a pointer to another array) member, that can be of different size that is specified during the creation of the class. Something like:

template<typename T>
class Buffer {

...
...
private:
  T events_[size]; // This size should be determined during compilation time.
}

I could use something like this:

template<typename T, int size>
class Buffer {

...
...
private:
  T events_[size]; // This size is determined during compilation time.
}

Is there a better way to do this?

Upvotes: 1

Views: 147

Answers (3)

john
john

Reputation: 87959

Seems your requirements are to have a 'flat' object of dynamic size.

I would do something like this

template <class T>
class Buffer
{
public:
    Buffer(size_t size) : size_(size) {}
    ...
private:
    size_t size_;
    const T* events() const { return reinterpret_cast<const T*>(this + 1); }
    T* events() { return reinterpret_cast<T*>(this + 1); }
};

Buffer<int>* buf = new char[sizeof(Buffer<int>) + n*sizeof(int)];
new (buf) Buffer<int>(n);

The events methods can be used to access the events, which exist just past the end of the Buffer object.

It's ugly because of the two step object creation process and the fact that Buffer must be dynamically allocated. But I think it's the best that can be done to meet your requirements. Also if T is a non-POD type then you need to make sure those are initialised too.

Upvotes: 0

edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31871

That is a perfectly acceptable way to do what you want. If you know the size you want at compile-time a template parameter is a good approach. It is standards compliant and doesn't involve any trickery. What more could you want?

Look at std:array to see this approach being used in the standard library.

Upvotes: 2

Tristan Brindle
Tristan Brindle

Reputation: 16824

template<typename T>
class Buffer {

    Buffer(std::size_t size) : events_(new T[size]) {}
    ~Buffer() { delete[] events_; }

private:
    T* events_;
}

is the closest you're going to be able to get without using compiler-specific extensions allowing C99 VLAs in C++. In standard C++, array sizes are fixed at compile-time, and that's that -- if you want the size decided at run-time, you have to use heap allocation.

Of course, using std::vector<T> to wrap the heap allocation in a nice API is a much better idea than rolling your own :-)

Upvotes: 0

Related Questions