首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于复杂类型数组的静态初始化

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

Stack Overflow用户
提问于 2019-04-05 23:23:19
回答 2查看 215关注 0票数 2

我需要用自定义分配器初始化的静态向量数组,以便在外部ram中存储我的数据(每个16字节)。我使用Howard Hinnant short alloc来做到这一点,到目前为止还不错。

我使用的是GCC和C++14:

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

// ---------------
// 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};

我一开始有2个内存池,但我需要98304个...我完全被困在初始化这些元素的数组上。

我试过这个:

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

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]};

如果我允许复制构造函数(这很可能是一个坏主意)

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]};

有没有人有其他方法初始化这个的线索?

编辑

非常感谢你的回答!实际上,我需要使用自定义分配器(short_alloc,在我的例子中重定向到arena )来实例化我的向量。所以我需要用竞技场来建造它们。每个竞技场在外部ram存储器中存储和分配一个数组,short_alloc是符合标准要求的自定义分配器本身。

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

除非我可以更改向量的分配器,否则我看不到任何其他的解决方案。

arena中的move构造函数解决了我的部分问题,我仍然有:

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::v0{Sequencer::arena0};

我在初始化short_alloc(arena_type& a)时调用,这没问题。为什么我无法多次执行此操作?

当然,如果有人有一个想法来避免这个巨大的initializer_list,我正在倾听!

我后来尝试在short_alloc类中设置竞技场引用,但到目前为止都没有成功。引用不能为空,我不想更改所有这些不是用指针编写的代码,并使用对虚拟竞技场的引用初始化FixedVectors会导致相同的初始问题。

谢谢,

EN

回答 2

Stack Overflow用户

发布于 2019-04-08 23:37:09

问题是std::vector的构造函数来自一个分配器is explicit。当你执行FixedVector fv{myArena}; all时,这是很好的,因为你在这里显式地构造了一个FixedVector。但是对于FixedVectors的数组,你是在做list initialization。添加大括号是不够的,你需要显式地拼写出构造函数。

用于演示的示例:

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

请注意,这不仅单调乏味,而且容易导致初始化顺序失败。更不用说普通数组不是很好的现代C++风格(但这是一个正交问题)。

票数 2
EN

Stack Overflow用户

发布于 2019-04-06 02:15:52

  1. arena定义移动构造函数。你应该有这样的东西:

//模板或其他类arena { public: arena(char arr[]) { /*...*/ } //我假设你是这样的。它仍然存在。arena(const arena&) = delete;//如果你没有,定义你的移动构造函数,和//只是从移动的实例移动(分配)缓冲区指针,等等。//与移动赋值运算符相同。竞技场(竞技场&&)=默认;竞技场&operator=(竞技场&&)=默认;// ... };

然后这句话

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

都会起作用的。编译器会将列表中的每个元素隐式转换为arena<600>,然后将内容移动到arenaa数组元素。

  • 您忘记了嵌套的花括号

编辑:和,正如Max Langhof指出的那样,显式的FixedVector构造是因为显式的std::vector构造函数只有一个分配器参数。

FixedVector序列器::v[]{序列器::arenaa,序列器::arenaa1};

已修复:

FixedVector Sequencer::v[]{FixedVector{Sequencer::arenaa},FixedVector{Sequencer::arenaa1}};

在我看来,如果你想在这些数组中有over9000元素而不是2元素,那么在初始化时填充你的静态数组似乎是无用的,就像我从你的问题中理解的那样。我认为您不希望在这些初始化器列表中硬编码over9000元素。用缺省值(例如为空)初始化它们,然后在循环中分配所需的值会更聪明。您可以在statics周围创建一个包装器结构,然后创建它的静态实例,然后在struct构造函数中填充数组。可能是这样的:

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;
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55538730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档