我有一个T*缓冲区,其中len包含类型的元素T.std::vector<T>出于某些原因,我需要以a的形式提供这些数据.据我所知,我无法构造一个使用我的缓冲区作为其内部存储的向量.这是为什么?
笔记:
我想编写一个带有提供读取功能的接口的库.C风格的数组容易出错,但允许传递任何大小的缓冲区.C++数组更安全,但强加于大小.
// interface.h
// C-style array
int read (std::uint8_t* buf, size_t len);
// C++ array
int read (std::array<std::uint8_t, 16>& buff)
Run Code Online (Sandbox Code Playgroud)
我怎样才能拥有两全其美?
我在考虑函数模板,但对于库接口来说似乎并不实用.
template <size_t N>
int read (std::array<std::uint8_t, N>& buf);
Run Code Online (Sandbox Code Playgroud)
编辑
std::vector可能是一个很好的候选人,但如果我们考虑char*并且std::array没有动态分配.
编辑我喜欢很多解决方案gsl::span.我坚持使用C++ 14所以没有std::span.我不知道使用第三个库(gsl)是否会成为问题/允许.
编辑我不认为使用char其他类型可能会对答案产生一些影响,所以更清楚的是操作字节.我char改为std::uint8_t
编辑由于C++ 11保证返回std::vector将被移动而不被复制,因此返回std::vector<std::uint8_t>是可以接受的.
std::vector<std::uint8_t> read();
Run Code Online (Sandbox Code Playgroud) 据我所知,std::string_view是一个非所属参照字符串之间的主要差异std::string_view,并std::string有
现在,为什么std :: string_view不适用于其他类型?或者为什么这个实现仅适用于std::string?
例如:如果我们有类似的<T>generic_view地方T可以是任何类型,包括自定义类型.
有了这个,可以使用而不是使用const T& as函数参数<T>generic_view.而且其他优点std::string_view也很有用,如分配,复制等.
编写下面代码的正确方法是什么?
我有一个内存管理器,它提供了我char *的,但我需要使用数组uint32_t.我如何解决严格的别名规则?我理解,对于单个对象,建议只复制内容,memcpy()但对于一组对象,该解决方案是不可接受的.
char* ptr = manager()->Allocate(1000 * sizeof(uint32_));
uint32_t* u32ptr = reinterpret_cast<uint32_t*>(ptr);
....
u32ptr[x] = y;
Run Code Online (Sandbox Code Playgroud) c++ pointers dynamic-memory-allocation reinterpret-cast c++11
C++20std::span是一个非常好的编程接口。但是似乎没有一种简单的方法来获得跨度。这是我想要做的:
#include <iostream>
#include <span>
#include <string>
#include <vector>
void print(std::span<std::span<wchar_t>> matrix) {
for (auto const& str : matrix) {
for (auto const ch : str) {
std::wcout << ch;
}
std::wcout << '\n';
}
}
int main() {
std::vector<std::wstring> vec = {L"Cool", L"Cool", L"Cool"};
print(vec);
}
Run Code Online (Sandbox Code Playgroud)
这不编译。我该怎么做?
假设我有两个缓冲区:
uint8_t* buf1[100];
uint8_t* buf2[10];
uint8_t* buf3[90];
Run Code Online (Sandbox Code Playgroud)
哪里buf1充满了数据,我需要将这些数据的 10 个字节传递buf2给buf3. 有没有办法在不复制的情况下做到这一点?
如果没有,是否有std::vector可以在不复制的情况下进行拼接的高级库(如)?
通过引用返回向量元素是不好的做法吗?
class X{
vector<Y> v;
public:
Y& getRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
void addToVectorOfY(Y y){
v.push_back(move(y));
}
};
Run Code Online (Sandbox Code Playgroud)
虽然这是有效和干净的,但问题在于它打破了封装.如果v是一个向量,并且是一个类的私有成员,则调用者现在将拥有一个私有向量中的元素的引用,它们不仅可以从中读取,还可以分配给(覆盖).
可以做到这一点
x.getRefFromVectorOfY(0).setNumber(7); //not bad..actually good
Run Code Online (Sandbox Code Playgroud)
要么
x.getRefFromVectorOfY(0) = move(Y2); //very bad!
Run Code Online (Sandbox Code Playgroud)
甚至
Y3 = move(x.getRefFromVectorOfY(0)); //OMG
Run Code Online (Sandbox Code Playgroud)
当然,我们可能会返回一个const,而只允许const操作.
按值返回元素效率较低,因为它是副本.
如果get方法是将元素移出向量以按值返回,则向量将丢失数据完整性,因为它将不再存储已移出的数据(元素将在向量内重置为默认状态...所以......仍然留在向量中,但作为垃圾数据).
我为什么要这样做?观点
如果您遵循零规则,并且您在类中有一个私有向量成员,则需要方便的方法来设置和设置向量.这提出了如何返回值的问题.
ref返回的问题是它破坏了封装,除非它是const ref.
那么,我应该只返回一个const ref强制任何值的设置来使用setVector方法吗?这个问题是有时你存储自定义类型...就像向量中的Y ..你需要访问Y的非const方法.虽然const&保护向量元素不被向量中的重置或覆盖,但它也阻止调用者使用返回的元素非const方法.
所以如果我只返回const&...我做不到
x.getRefFromVectorOfY(0).setNumber(7); //Y has a setNumber method
Run Code Online (Sandbox Code Playgroud)
那将是一个问题.这将是一个问题,因为我不想在X类中重新实现Y的任何方法.这将是另一层间接和大量代码冗余.这反对回报const和一般政策.在许多情况下不实用.
所以我必须基于返回值的常量来覆盖,这是你不能做的.
所以我必须有两个带有diff名称的函数,一个返回const&...而另一个只返回一个&.那感觉很脏.
const Y& getConstRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
Y& getRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
Run Code Online (Sandbox Code Playgroud)
编辑
我添加了这个表来总结问题和目标.
我希望X类调用者能够 …
在我的应用程序的结构中,一个对象具有一个向量是另一个向量的子集是有意义的。我的意思是说,较小的存储包含在较大的存储中。
这在C ++中可能吗?我保证这两个向量都不会被调整大小,并且我可能可以做到这一点,以使子向量在包含向量之前被破坏。
最初,我认为创建从迭代器到大向量的子向量可以解决问题,但这会产生一个副本。我真的想要重定向裸指针。
有没有办法达到与此相同的效果,
std::list<int> l(10);
std::iota(l.begin(), l.end(), -4);
Run Code Online (Sandbox Code Playgroud)
与常规int a[]?
或者,以下是唯一的解决方法:
for (iterator itr = begin; itr != end; ++itr)
/* ... visit *itr here ... */
Run Code Online (Sandbox Code Playgroud)