c++ - 分配 std::vector到 std::vector无需复制内存
问题描述
我有一个返回一个函数std::vector<std::byte>
我知道这std::byte
不是字符类型也不是整数类型,并且只能通过类型转换将其转换为 char。到目前为止,一切都很好。
所以我想(在我知道向量只包含字符数据的情况下)将底层缓冲区的所有权从std::vector<std::byte>
a 转移到std::vector<char>
using std::move
,以避免复制整个底层缓冲区。
当我尝试这样做时,我收到此错误:
不存在从“std::vector<std::byte, std::allocatorsstd::byte>”到“std::vector<char,std::allocator>”的合适的用户定义转换
这完全可能使用 C++ 吗?我认为有真正的用例想要这样做
解决方案
我可能会将数据保留在原始数据中,vector<byte>
并创建一个小类来保留对原始数据的引用,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';
}
}
输出:
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);
推荐阅读
- ios - 出于安全原因,如何在 iOS 中从内存中删除字符串?它甚至需要还是iOS自己处理
- javascript - Create a countdown timer on button click when value is entered in text box : Javascript
- c# - 如何在 C# 中使用 System.XML 将命名空间标记添加到 XML
- asp.net-core - 如何在同一个 IIS 站点上运行 API 和网站
- python - Modify List using For loop in Python
- azure-devops - 绑定已经存在于不同的网站
- python - 如何检查对我的机器人使用命令的人的用户 ID
- java - 使用 Azure 部署 Java webapp
- java - 如何使用 itext 从具有内置编码的 pdf 中提取 PRStream?
- asp.net-web-api - WebAPI 方法应该如何返回错误响应?