简体   繁体   English

复杂类型数组的静态初始化

[英]Static initialization for complex type array

I need static array of vectors initialized with custom Allocators in order to store my data (16 bytes each) in external ram. 我需要使用自定义分配器初始化的向量的静态数组,以便将我的数据(每个16字节)存储在外部ram中。 I use Howard Hinnant short alloc to do so, so far so good. 我使用Howard Hinnant的短分配来做到这一点,到目前为止到目前为止还不错。

I use GCC and C++14: 我使用GCC和C ++ 14:

Sequencer.h Sequencer.h

    using FixedVector = std::vector<SequencerNoteEvent, short_alloc<SequencerNoteEvent, kBytesChunkMax, 4>>;

    /* memory pool */
    static char sequencerNoteEvent[2][600] __attribute__((section(".masection")));

    /* Declaration des différentes zones pour chaque vecteur */
    static arena<600> arena0 __attribute__((section(".masection")));
    static arena<600> arena1 __attribute__((section(".masection")));

     /* Declaration des Vectors utilisants les pools */
    static FixedVector v0 __attribute__((section(".masection")));
    static FixedVector v1 __attribute__((section(".masection")));

Sequencer.cpp Sequencer.cpp

// ---------------
// STATIC VARIABLE
// ---------------
char Sequencer::sequencerNoteEvent[kMaxChunks][kBytesChunkMax];

arena<kBytesChunkMax> Sequencer::arena0{Sequencer::sequencerNoteEvent[0]};
FixedVector Sequencer::v0{Sequencer::arena0};
arena<kBytesChunkMax> Sequencer::arena1{Sequencer::sequencerNoteEvent[1]};
FixedVector Sequencer::v1{Sequencer::arena1};

I started with 2 memory pool, but i need 98304 of them... And i am totally stuck at initializing an array of these. 我从2个内存池开始,但是我需要98304个内存池...而且我完全无法初始化这些数组。

I tried this : 我尝试了这个:

Sequencer.h Sequencer.h

  /* Declaration de la memory pool */
  static char sequencerNoteEvent[2][600] __attribute__((section(".masection")));

  static arena<600> arenaa[2] __attribute__((section(".masection")));

  static FixedVector v[2] __attribute__((section(".masection")));

Sequencer.cpp Sequencer.cpp

arena<600> Sequencer::arenaa[]{Sequencer::sequencerNoteEvent[0], Sequencer::sequencerNoteEvent[1]};
FixedVector Sequencer::v[]{Sequencer::arenaa[0], Sequencer::arenaa[1]};
 error: use of deleted function 'arena<N, alignment>::arena(const arena<N, alignment>&) [with unsigned int N = 600; unsigned int alignment = 4]'
 arena<kBytesChunkMax> Sequencer::arenaa[]{Sequencer::sequencerNoteEvent[0], Sequencer::sequencerNoteEvent[1]};

and if i allow the copy constructor (which is very likely to be a bad idea) 如果我允许复制构造函数(这很可能是个坏主意)

error: conversion from 'arena<600>' to non-scalar type 'pyrapro::FixedVector' {aka 'std::vector<pyrapro::SequencerNoteEvent, short_alloc<pyrapro::SequencerNoteEvent, 600, 4> >'} requested
 FixedVector Sequencer::v[]{Sequencer::arenaa[0], Sequencer::arenaa[1]};

Does someone have any clue of another way to initialize this ? 有人有其他线索可以初始化此方法的线索吗?

EDIT 编辑

Thanks a lot for your answer ! 非常感谢您的回答! Actually i need to instantiate my vectors with custom allocators (short_alloc which redirect to arena in my case). 实际上,我需要使用自定义分配器(在我的情况下重定向到竞技场的short_alloc)实例化我的向量。 So i need them to be constructed with an arena. 所以我需要用竞技场建造它们。 Each arena stores and allocate an array in an external ram memory and short_alloc is the custom allocator itself which meets the requirements of the standard. 每个竞技场在外部ram内存中存储并分配一个数组,short_alloc是满足标准要求的自定义分配器本身。

short_alloc(arena_type& a) noexcept : a_(a) {}

Unless i can change the allocator of a vector once it has already been constructed i don't see any other solution. 除非一旦构造了向量就可以更改其分配器,否则我看不到任何其他解决方案。

The move constructor in arena solved part of my issue, i still have : 竞技场中的move构造函数解决了部分问题,但我仍然有:

error: conversion from 'arena<600>' to non-scalar type 'pyrapro::FixedVector' {aka 'std::vector<pyrapro::SequencerNoteEvent, short_alloc<pyrapro::SequencerNoteEvent, 600, 4> >'} requested

When i do this : 当我这样做时:

FixedVector Sequencer::v0{Sequencer::arena0};

i calls at initialization short_alloc(arena_type& a) which is fine. 我打电话给short_alloc(arena_type&a)初始化,这很好。 Why i am unable to do this multiple times ? 为什么我无法多次执行此操作?

Of course if someone has an idea avoiding this huge initializer_list i am listening ! 当然,如果有人有想法避免使用这个庞大的initializer_list,我在听!

I tried to set the arena reference in short_alloc classes later with no success so far. 我试图稍后在short_alloc类中设置arena引用,但到目前为止没有成功。 References can't be null, i don't want to change all of this code i didn't write with pointers and init the FixedVectors with a reference to a dummy arena leads to the same initial issue. 引用不能为null,我不想更改所有我没有使用指针编写的代码,并且通过引用虚拟舞台来初始化FixedVectors会导致相同的初始问题。

Thanks, 谢谢,

The problem is that std::vector 's constructor from an allocator is explicit . 问题是分配器中std::vector的构造函数是显式的 When you do FixedVector fv{myArena}; 当您执行FixedVector fv{myArena}; all is good because you are explicitly constructing a FixedVector here. 一切都很好,因为您在这里显式构造了FixedVector But with the array of FixedVector s, you are doing list initialization . 但是,使用FixedVector的数组,您正在执行列表初始化 Adding curly braces is not sufficient, you need to explicitly spell out the constructor. 添加花括号是不够的,您需要明确拼出构造函数。

Example to demonstrate: 示例说明:

using FV = std::vector<int>;
using FVA = FV::allocator_type;

FVA fva[3]{};

//FV fv[]{1, 2, 3}; // error: cannot convert from int to vector<int>
//FV fv[]{{1}, {2}, {3}}; // ok (nested list initialization)

//FV fv[]{fva[0], fva[1], fva[2]}; // error: cannot convert from FVA to FV
FV fv[]{FV{fva[0]}, FV{fva[1]}, FV{fva[2]}}; // ok

https://godbolt.org/z/X9a67T https://godbolt.org/z/X9a67T

Take note that this is not only tedious but also prone to initialization order fiasco. 请注意,这不仅繁琐,而且容易发生初始化顺序的惨败。 Not to mention that plain arrays are not good modern C++ style (but that's an orthogonal issue). 更不用说普通数组不是现代的C ++风格(但这是一个正交的问题)。

  1. Define move constructor for arena . arena定义move构造函数。 You should have something like this: 您应该具有以下内容:

     // template or something class arena { public: arena(char arr[]) { /*...*/ } // I assume you have it like this. It remains. arena(const arena&) = delete; // Define your move constructor if you don't have one and // just move (assign) buffer pointers, etc. from moved instance to this. // Same for move assignment operator. arena(arena&&) = default; arena& operator=(arena&&) = default; // ... }; 

    Then the line 然后线

     arena<600> Sequencer::arenaa[]{Sequencer::sequencerNoteEvent[0], Sequencer::sequencerNoteEvent[1]}; 

    will work. 将工作。 Compiler will implicitly cast each element in the list to arena<600> and then move the contents to arenaa array elements. 编译器会将列表中的每个元素隐式转换为arena<600> ,然后将内容移动到arenaa数组元素。

  2. You forgot nested curly brackets 你忘了嵌套花括号

    Edit: and, as Max Langhof pointed out, explicit FixedVector construction because of explicit std::vector constructor with single allocator argument. 编辑:并且,正如Max Langhof所指出的,由于具有单个分配器参数的显式std::vector构造函数,因此进行了显式FixedVector构造。

     FixedVector Sequencer::v[]{Sequencer::arenaa[0], Sequencer::arenaa[1]}; 

    Fixed: 固定:

     FixedVector Sequencer::v[]{FixedVector{Sequencer::arenaa[0]}, FixedVector{Sequencer::arenaa[1]}}; 

Still it seems to me useless to fill your static arrays in initialisation, if you want to have over9000 elements instead of 2 in these arrays, as far as I understand from your question. 就我所知,如果要在这些数组中包含超过9000个元素而不是2个元素,那么在初始化中填充静态数组似乎仍然没有用。 I think you don't want to hardcode over9000 elements in those initializer lists. 我认为您不想对那些初始化列表中的9000多个元素进行硬编码。 It will be more clever to initialise them with default values (empty for example), and then assign needed values in a loop. 将它们初始化为默认值(例如为空),然后在循环中分配所需的值会更聪明。 You can make a wrapper struct around your statics and create its static instance instead, then fill arrays in struct constructor. 您可以围绕静态对象创建包装器结构,并创建其静态实例,然后在struct构造函数中填充数组。 Something like this maybe: 可能是这样的:

class Sequencer {
    static struct Wrapper {
        using FixedVector = std::vector<SequencerNoteEvent>;
        char sequencerNoteEvent[2][600];
        arena<600> arenaa[2];
        FixedVector v[2];
        Wrapper() { 
            for (int i = 0; i < 2; i++) {
                arenaa[i] = arena<600>(sequencerNoteEvent[i]);
                v[i].emplace_back(arenaa[i]);
            }
        }
    } s_instance;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM