简体   繁体   English

如何使用可变长度的数据块配置编译时const对象?

[英]How can I have a compile-time const object configured with a chunk of data of variable length?

Currently I'm struggling with something like this: 目前我正在努力解决这样的问题:

class Command final {
    const std::vector<uint8_t> cmd;
public:
    constexpr Command(const std::initializer_list<uint8_t> cmd_)
        :cmd(cmd_)
        {}
    void copyToWithSlightModifications(uint8_t* buf, size_t len) { /*...*/ }
    std::string getSomeInformation() { /*...*/ }
}

const Command cmd1({ 0x01, 0x02, 0x03 });
const Command cmd2({ 0x01, 0x02, 0x03, 0x04 });
// lots more of these

Of course, std::vector is not something that works here, but it's here as it expresses my intent best. 当然, std::vector不是在这里工作的东西,但它在这里,因为它最好地表达了我的意图。 I tried std::array and a few other ideas, but also have failed. 我尝试过std::array和其他一些想法,但也失败了。

Background: this is for embedded development, so I'm tight on resources and consting things tends to put them to flash where memory is cheap. 背景:这是针对嵌入式开发的,所以我对资源很紧张,并且常常将内容放到内存便宜的闪存中。 Doing it as a real vector will put this into scarce RAM memory. 将它作为一个真正的向量将它放入稀缺的RAM内存中。 This is on gcc version 5.2.0. 这是在gcc版本5.2.0上。

TL;DR: I need to have a variable length container that I can put as a field on a const object with and initialize it in constexpr context. TL; DR:我需要一个可变长度的容器,我可以把它作为一个字段放在一个const对象上,并在constexpr上下文中初始化它。 Any idea what that might look like? 知道那可能是什么样的吗? Doesn't have to be anything fancy, if it's a uint8_t* and a size_t with it's size, that will work too. 没有任何花哨的东西,如果它是一个uint8_t*和一个带有它的尺寸的size_t ,它也会起作用。

Going off of your description and the code snippet, this seems to fit the criteria. 关闭您的描述和代码片段,这似乎符合标准。

template<size_t N>
class Command
{
    uint8_t cmd[N];
public:
    template<typename... Args>
    constexpr Command(Args... args) : cmd{uint8_t(args)...}
    {
        static_assert(sizeof...(Args) == N,
                      "argument count mismatch");
    }
};

constexpr Command<4> cmd4{0, 1, 2, 3};
constexpr Command<2> cmd2{0, 1};

You may also write a helper function to avoid explicitly typing the argument count 您还可以编写辅助函数以避免显式键入参数计数

template<typename... Args>
constexpr Command<sizeof...(Args)> make_command(Args... args)
{
    return {args...};
}

constexpr auto cmd4 = make_command(0, 1, 2, 3);
constexpr auto cmd2 = make_command(0, 1);

Alternatively, in C++17 there is template deduction guides 或者,在C ++ 17中有模板推导指南

template<typename... Args>
Command(Args...) -> Command<sizeof...(Args)>;

constexpr Command cmd4{0, 1, 2, 3};
constexpr Command cmd2{0, 1};

Note however, a different sized Command is a different type, meaning they won't fit in a container. 但请注意,不同大小的Command是不同的类型,这意味着它们不适合容器。

In deeply embedded you usually use circular buffers so solve this kind of problem. 在深度嵌入式中,您通常使用循环缓冲区来解决此类问题。 They have a fixed maximal size but depending on implementation they behave just like lists. 它们具有固定的最大大小,但根据实现,它们的行为就像列表一样。 Unfortunately the standard c++ library does not have any circular buffers but there are plenty of tutorials on the web. 不幸的是,标准的c ++库没有任何循环缓冲区,但网上有很多教程。

I doublt you can use boost library on your restricted system but in case you do you can simply use boost::circular_buffer 我怀疑你可以在受限制的系统上使用boost库,但万一你可以使用boost :: circular_buffer

Some other pages that might help you implement an circular buffer suitable for you might be this or this 其他一些可能帮助您实现适合您的循环缓冲区的页面可能就是这个或者这个

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

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