How does one suppress the automatic initialization and destruction of a type? While it is wonderful that T buffer[100]
automatically initializes all the elements of buffer
, and destroys them when they fall out of scope, this is not the behavior I want.
#include <iostream>
static int created = 0,
destroyed = 0;
struct S
{
S()
{
++created;
}
~S()
{
++destroyed;
}
};
template <typename T, size_t KCount>
class fixed_vector
{
private:
T m_buffer[KCount];
public:
fixed_vector()
{
// some way to suppress the automatic initialization of m_buffer
}
~fixed_vector()
{
// some way to suppress the automatic destruction of m_buffer
}
};
int main()
{
{
fixed_vector<S, 100> arr;
}
std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}
The output of this program is:
Created: 100
Destroyed: 100
I would like it to be:
Created: 0
Destroyed: 0
My only idea is to make m_buffer
some trivially constructed and destructed type like char
and then rely on operator[]
to wrap the pointer math for me, although this seems like a horribly hacked solution. Another solution would be to use malloc
and free
, but that gives a level of indirection that I do not want.
The reason why I want this is because I am making a container and I do not want to pay for the initialization overhead of things that I will not use. For example, if my main
function was:
int main()
{
{
std::vector<S> vec;
vec.reserve(50);
}
std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}
The output would be correct:
Created: 0
Destroyed: 0
This code:
has exactly the output you want - I'm not sure what your question is.
You may want to look into
boost::optional
A specialization is done for class type that wraps them into an
optional
, thus calling the constructor/destructor lazily. For non-class types, we don't need that wrapping. Not wrapping them means we can treat&a[0]
as a contiguous memory area and pass that address to C functions that want an array.boost::in_place
will create the class types in-place, without using a temporaryT
or its copy constructor.Not using inheritance or private members allow the class to stay an aggregate, allowing a convenient form of initialization
You can create the array as array of
char
s and then use placementnew
to create the elements when needed.After re-reading your question it seems that you want a sparse array, this sometimes goes by the name of map ;o) (of course the performance characteristics are different...)
If you want to be like vector, you should do something like this:
This code is obviously for demonstration only, I have omitted my_vector's copy-constructor and any tracking on what's created and what not (calling destructor on a location you haven't called constructor for is probably undefined behavior). Also, STL's
vector
allocations and deallocations are abstracted away through the use of allocators (the second template argument ofvector
).Hope that helps
You can have a look at the way it's done with the STL containers, but I doubt you can spare yourself
malloc
s andfree
s