Reputation: 2649
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
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
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
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