簡體   English   中英

分配 std::vector<std::byte> 到 std::vector<char> 不復制 memory</char></std::byte>

[英]Assign std::vector<std::byte> to std::vector<char> WITHOUT copying memory

我有一個返回std::vector<std::byte>的 function

我知道std::byte不是字符類型也不是整數類型,並且只能通過類型轉換將其轉換為 char 。 到目前為止,一切都很好。

所以我想(在我知道向量只包含字符數據的情況下)使用 std:: 將底層緩沖區的所有權從std::vector<std::byte>轉移到 std std::move std::vector<char> std::move ,以避免復制整個底層緩沖區。

當我嘗試這樣做時,我收到此錯誤:

不存在從“std::vector<std::byte, std::allocatorsstd::byte>”到“std::vector<char,std::allocator>”的合適的用戶定義轉換

使用 C++ 是否有可能? 我認為有真正的用例想要這樣做

我可能會將數據留在原始vector<byte>中,並制作一個小的 class 來保留對原始vector<byte>的引用,並在需要時進行必要的轉換。

例子:

#include <cstddef>
#include <iostream>
#include <vector>

template<typename T>
struct char_view {
    explicit char_view(std::vector<T>& bytes) : bv(bytes) {}

    char_view(const char_view&) = default;
    char_view(char_view&&) = delete;
    char_view& operator=(const char_view&) = delete;
    char_view& operator=(char_view&&) = delete;

    // capacity
    size_t element_count() const { return bv.size(); }
    size_t size() const { return element_count() * sizeof(T); }

    // direct access
    auto data() const { return reinterpret_cast<const char*>(bv.data()); }
    auto data() { return reinterpret_cast<char*>(bv.data()); }

    // element access
    char operator[](size_t idx) const { return data()[idx]; }
    char& operator[](size_t idx) { return data()[idx]; }

    // iterators - with possibility to iterate over individual T elements
    using iterator = char*;
    using const_iterator = const char*;

    const_iterator cbegin(size_t elem = 0) const { return data() + elem * sizeof(T); }
    const_iterator cend(size_t elem) const { return data() + (elem + 1) * sizeof(T); }
    const_iterator cend() const { return data() + size(); }

    const_iterator begin(size_t elem = 0) const { return cbegin(elem); }
    const_iterator end(size_t elem) const { return cend(elem); }
    const_iterator end() const { return cend(); }
    
    iterator begin(size_t elem = 0) { return data() + elem * sizeof(T); }
    iterator end(size_t elem) { return data() + (elem + 1) * sizeof(T); }
    iterator end() { return data() + size(); }

private:
    std::vector<T>& bv;
};

int main() {
    using std::byte;

    std::vector<byte> byte_vector{byte{'a'}, byte{'b'}, byte{'c'}};

    char_view cv(byte_vector);

    for(char& ch : cv) {
        std::cout << ch << '\n';
    }
}

Output:

a
b
c

如果您只需要const訪問,一個更簡單的選擇可能是創建一個string_view

template<typename T>
std::string_view to_string_view(const std::vector<T>& v) {
    return {reinterpret_cast<const char*>(v.data()), v.size() * sizeof(T)};
}
//...
auto strv = to_string_view(byte_vector);

std::vector不允許附加或分離到 memory 分配,除了從完全相同類型的向量移動。 已被提出,但人們對附加分配器等提出了(有效的)反對意見。

function 返回vector<byte>會限制您使用vector<byte>作為數據容器,除非您想將數據復制出來。

當然,您可以將字節別名為char就地進行字符操作。

您可以通過強制轉換來實現這一點,如下所示。 這是合法的,因為轉換是針對char引用(如果轉換為任何其他類型,它將是 UB),但是至少使用 gcc,您仍然必須使用-fno-strict-aliasing編譯它以使編譯器警告靜音。 無論如何,這是演員表:

std::vector <char> char_vector = reinterpret_cast <std::vector <char> &&> (byte_vector);

這是一個現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM