c++ - 我怎样才能让编译时 const 对象配置有可变长度的数据 block ?

标签 c++ c++11 constexpr

目前我正在为这样的事情苦苦挣扎:

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

当然,std::vector 在这里不起作用,但它在这里是因为它最能表达我的意图。我尝试了 std::array 和其他一些想法,但都失败了。

背景:这是针对嵌入式开发的,所以我的资源很紧张,const 的东西往往会把它们放在内存便宜的地方。将它作为一个真正的 vector 来做会将其放入稀缺的 RAM 内存中。这是在 gcc 版本 5.2.0 上。

TL;DR:我需要一个可变长度的容器,我可以把它作为一个字段放在一个 const 对象上,并在 constexpr 上下文中初始化它。知道那会是什么样子吗?不必是任何花哨的东西,如果它是一个 uint8_t* 和一个具有它大小的 size_t,那也可以。

最佳答案

从您的描述和代码片段来看,这似乎符合标准。

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

你也可以编写一个辅助函数来避免显式输入参数计数

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);

或者,在 C++17 中有模板推导指南

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

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

但是请注意,不同大小的 Command 是不同的类型,这意味着它们不适合容器。

关于c++ - 我怎样才能让编译时 const 对象配置有可变长度的数据 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47429767/

相关文章:

c++ - 解释 c/c++ 赋值期间逗号的异常使用

c++ - 我如何在 c 中读取一个巨大的 .gz 文件(超过 5 gig 未压缩)

c++ - Linux 的 VirtualQueryEx 替代方案 - 如何获取另一个进程的虚拟内存范围

c++ - 用于解释自定义 c++11 属性的 Clang/GCC 插件

c++ - 修改集合内对象的可变成员是否安全?

c++ - 将 vector 指针 move 到 C++ 中的 vector 派生类?

c++ - Clang 3.7.0 提示类不是文字,因为它不是聚合并且没有 constexpr 构造函数

c++ - constexpr 和 std::cout 处理函数但不处理 lambda

c++ - 没有 constexpr memcpy 编译器支持的 bit_cast 可能吗?

c++ - 模板类中具有未知类型属性的默认构造函数