首页 > 解决方案 > 在字节数组中连接结构

问题描述

我想连接两个结构。问题是我无法将该 struct 转换为 a std::span,因为 span 的构造函数不支持void*. 我也使用相同的 concat 函数进行连接std::vector<uint8_t>,因此对该函数所做的任何更改都不应该影响它。如果可以将 struct 转换为vector<uint8_t>,我将能够更改std::span<uint8_t>为相同的向量。我怎样才能做到这一点?

address_t address{};
memcpy(address.country, country, sizeof country);
memcpy(address.city, city, sizeof city);
memcpy(address.state, state, sizeof state);
address.zip_code = zip_code;

...

const auto& a = reinterpret_cast<void*>(&address);

auto c = utils::concat(a, b);

片段

__declspec(align(16))
typedef struct
{
    std::wchar_t country[30];
    std::wchar_t city[50];
    std::wchar_t state[50];
    std::uint32_t zip_code;
} address_t;

namespace utils
{
    inline std::vector<std::uint8_t> concat(const std::span<std::uint8_t>& a)
    {
        return std::vector<std::uint8_t>(a.data(), a.data() + a.size());
    }
    
    template <typename... Args>
    std::vector<std::uint8_t> concat(const std::span<std::uint8_t>& a, Args&... args)
    {
        auto vec = std::vector<std::uint8_t>(a.data(), a.data() + a.size());
        (vec.insert(vec.end(), args.begin(), args.end()), ...);

        return vec;
    }
}

标签: c++c++20

解决方案


您可以提供一种将 an 重新解释address为跨度的方法:

auto to_span(address const& a) -> std::span<uint8_t const> {
    return {(uint8_t const*)&a, sizeof(a)};
}

然后你的其他东西就可以工作了:

auto c = utils::concat(to_span(address), to_span(other_address));

这可以概括为支持可简单复制的类型。


concat当前将参数作为const std::span<std::uint8_t>&. 您通常希望span按值获取(它是一种小型、可轻松复制的类型,您几乎从不关心 的身份span。此外,当您不修改的内容时span(因为您不在这里),您要确保它是span过度const数据。

也就是说,您的参数应该具有 type std::span<uint8_t const>

这可以确保您不会通过修改span(这很重要,并且允许您传递不可变的东西,就像我to_span上面的那样),而接受const&只会保护您不修改span本身(这根本不重要)。


推荐阅读