2

I tried to write an "inline-vector" class for storing a number of elements on the stack conveniently:

template<typename T, size_t size_ = 256>
struct InlineVector{
    T content[size_];
    size_t num;

    T() : num(0) {}

    ~T() { for(size_t s = 0; s < num; s++){ content[s]->~T(); } }

    template<typename _Up, typename... _Args>
    void emplace_back(_Args&&... __args) { new (&content[num++]) T(__args); }

    T& get(size_t i) { assert(i < num); return content[i]; }


}

For efficiency reasons, I want that content is not initialized in X's constructor, even if T has only a non-trivial constructor. As you see, the content is intialized later with placement new when it is actually inserted. However, C++ seems to enforce that all elements of content must be initialized in the initialization of X. For example, this does not compile:

struct Y{ Y(int){} }

X<Y> foo; // compile error, no constructor for Y is called in the construction of X

So, how is it possible to have an array member that is not initialized, even if the array element type needs a constructor?

0

2 Answers 2

6

By making the array an array of chars and later placement new-ing into it. char is the only type you're allowed to do this with.

Whilst you're at it, then, you might as well write your own allocator instead (with the array as one of its members), and plug it into std::vector rather than re-inventing the whole shebang.

std::vector<int, YourAllocatorType<int, 256>> v;
Sign up to request clarification or add additional context in comments.

2 Comments

Interesting idea with the allocator. And thanks for the actual answer of using a char array, as the allocator would have the same problem as the vector. Seems there is no way around the char array, no matter whether writing an allocator or a vector.
@gexicide: Yep not really :)
1

So, how is it possible to have an array member that is not initialized, even if the array element type needs a constructor?

It's not for T x[n]... but you can point any old T* at properly aligned uninitialised memory, then manage your own ad-hoc construction and destruction. You could also explore creating a union with your type and say a char, and have an array of the unions....

2 Comments

I don't think union is permitted with members with non-trivial constructors. But it's not needed; a char array and cast is fine and as long as one of the types is char, well defined.
@JanHudec: there are restrictions around the type, but I believe they were relaxed substantially for C++11... certainly something to keep in mind. Don't have time to dig for exact details myself right now....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.