kamziro
kamziro

Reputation: 8170

resizing c++ vectors without calling their constructors

So I have this situation where I have:

std::vector<Coord3D> thevector;

where Coord3D is just a simple struct with 3 floats: x, y and z. The constructor also only simply has x = 0; y = 0; z = 0; etc.

Now, suppose I want to append the contents of another vector into thevector.

Is it possible to resize the vector's size into thevector.size() + theothervector.size(), without making c++ call Coord3D()'s constructor?

The reason is that I want to memcpy the contents of theothervector. initialising the contents with constructors turned out to take some time after some benchmark testing. std::loopfill also takes quite a bit of time.

So yeah, is there a way to resize vectors while bypassing constructors of the elements? Will this involve dodgy hacks?

Upvotes: 1

Views: 2227

Answers (4)

Paul Martz
Paul Martz

Reputation: 166

std::vectors all have an allocator, usually the default allocator. The allocator's construct() member function invokes the per-element constructor on your behalf.

To avoid invoking the per-element constructor, create your own allocator and ensure the construct() member function has an empty function body (or some other logic to decide at runtime whether or not to invoke the element's constructor).

After you create the vector with the custom allocator, just resize() the vector. There will be no per-element constructor invocation.

I have used this technique successfully to point a std::vector at a database's persistent storage. It avoids the per-element constructor (which would otherwise overwrite the DB's storage), and also avoids data copies (as the custom allocator was designed to know what part of the DB store to reference).

Upvotes: 5

Mahesh
Mahesh

Reputation: 34665

Is it possible to resize the vector's size into thevector.size() + theothervector.size(), without making c++ call Coord3D()'s constructor?

No, when you try to resize the size of the vector. When you resize the size of the vector, the elements of the vector needs to be copied to the new location and in this case, if I am not wrong, copy constructor of the class needs to be called.

As others said, you can any how call reserve. But the vector is empty with no elements.

Upvotes: 0

Mihran Hovsepyan
Mihran Hovsepyan

Reputation: 11108

You should enlarge their capacity and not size. For this use reserve(). And for getting current capacity use capcity().

This code will explain how:

std::vector<Coord3D> thevector;
thevector.reserve(n); //where n is size you want
Coord3D * vector_start = &(thevector[0]);
//do memcpy to vector_start

But this code is unsafe and related to implementation of std::vector.

Upvotes: 0

Yakov Galka
Yakov Galka

Reputation: 72549

thevector.insert(thevector.end(), theothervector.begin(), theothervector.end());

If Coord3D are bitwise-copyable the compiler should be able to optimize it to the same code as memcpy.

Upvotes: 8

Related Questions