2017-08-15 9 views
-2

の配列:可撓性部材の私は(しかし、C++で)必要なものC++

struct Element{ 
    bool deleted; 
    T value; 
} 
struct Chunk{ 
    Chunk* prev; 
    // other data 
    Element elements[];  // C99 flexible array member! 

    static make(std::size_t capacity){ 
     Chunk *chunk = static_cast<Chunk *>(std::malloc(sizeof(Chunk) + sizeof(Element) * capacity)); 
     // init data 
     return chunk; 
    } 
} 

しかし、C++は '柔軟な配列メンバー' はありません。だからこのようなことをした:

struct Element{ 
    bool deleted; 
    T value; 
} 
struct alignas(Element) Chunk{ // Chunk is always POD 
    Chunk* prev; 
    // other data 

    Element *elements() { 
     return static_cast<Element *>(static_cast<void *>(
      reinterpret_cast<unsigned char *>(this) + sizeof(Chunk) 
     )); 
    } 

    static make(std::size_t capacity){ 
     Chunk *chunk = static_cast<Chunk *>(std::malloc(sizeof(Chunk) + sizeof(Element) * capacity)); 
     // init data 
     // DO NOT INIT elements here. Will be placement newed' later. 
     return chunk; 
    } 
} 

質問は正しいですか?それともUBの原因ですか?正しく整列していますか?これはElement elements[1]よりも優れていますか?

P.S. stackoverflowでこの問題にいくつかの回避策がありますが、私はそれらのどれが正しいのかを知りませんでした。

+8

が見えます。 –

+0

@BaummitAugen - thxだが、それはない: – tower120

+0

それでは、私はその質問を理解していない。 –

答えて

1

私は、このソリューションで終わる:として使用することができます

template<class Header, class T> 
class FlexibleMemberArray { 
    struct alignas(T) AlignedHeader : Header{}; 

    Header* self(){ 
     return static_cast<Header*>(this); 
    } 

protected: 
    static Header* make(const int capacity) { 
     Header *chunk = static_cast<Header *>(std::malloc(sizeof(AlignedHeader) + sizeof(T) * capacity)); 
     return chunk; 
    } 

    inline T *elements() { 
     return static_cast<T *>(static_cast<void *>(reinterpret_cast<unsigned char *>(self()) + 
                  sizeof(AlignedHeader))); 
    } 
}; 

:あなたがここに `のstd :: vector`を再発明されているよう

struct Chunk : public FlexibleMemberArray<Chunk, int>{ 
    int capacity; 
    static void* operator new(std::size_t sz, int capacity) { 
     Chunk* self = make(capacity); 
     self->capacity = capacity; 
     return self; 
    } 

    using FlexibleMemberArray::elements; 
}; 

int main() { 
    std::unique_ptr<Chunk> chunk {new (30) Chunk}; 

    for(int i=0;i<chunk->capacity;i++){ 
     chunk->elements()[i] = i; 
    } 

    for(int i=0;i<chunk->capacity;i++){ 
     std::cout << chunk->elements()[i] << std::endl; 
    } 

    return 0; 
} 
関連する問題