use*_*228 35 c++ stl resize vector
使用向量,可以假设元素连续存储在内存中,允许范围[&vec [0],&vec [vec.capacity())用作普通数组.例如,
vector<char> buf;
buf.reserve(N);
int M = read(fd, &buf[0], N);
Run Code Online (Sandbox Code Playgroud)
但现在向量不知道它包含M个字节的数据,由read()外部添加.我知道vector :: resize()设置了大小,但它也清除了数据,因此在read()调用之后它不能用于更新大小.
是否有一种简单的方法可以将数据直接读入矢量并在之后更新大小?是的,我知道明显的解决方法,比如使用一个小数组作为临时读缓冲区,并使用vector :: insert()将它附加到向量的末尾:
char tmp[N];
int M = read(fd, tmp, N);
buf.insert(buf.end(), tmp, tmp + M)
Run Code Online (Sandbox Code Playgroud)
这是有效的(这就是我今天正在做的事情),但是如果我可以将数据直接放入向量中,那么在那里会有一个额外的复制操作,这是困扰我的.
那么,在外部添加数据时,是否有一种简单的方法来修改矢量大小?
Rob*_*obᵩ 24
vector<char> buf;
buf.reserve(N);
int M = read(fd, &buf[0], N);
Run Code Online (Sandbox Code Playgroud)
此代码片段调用未定义的行为.即使您保留了空间size(),也不能超出元素.
正确的代码如下:
vector<char> buf;
buf.resize(N);
int M = read(fd, &buf[0], N);
buf.resize(M);
Run Code Online (Sandbox Code Playgroud)
[&vec[0], &vec[vec.capacity())用作普通数组"不成立.允许的范围是[&vec[0], &vec[vec.size()).
看起来你可以在C++ 11中做你想做的事情(尽管我自己没有尝试过).您必须为向量定义自定义分配器,然后使用emplace_back().
首先,定义
struct do_not_initialize_tag {};
Run Code Online (Sandbox Code Playgroud)
然后使用此成员函数定义分配器:
class my_allocator {
void construct(char* c, do_not_initialize_tag) const {
// do nothing
}
// details omitted
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在不初始化数组的情况下向元素添加元素:
std::vector<char, my_allocator> buf;
buf.reserve(N);
for (int i = 0; i != N; ++i)
buf.emplace_back(do_not_initialize_tag());
int M = read(fd, buf.data(), N);
buf.resize(M);
Run Code Online (Sandbox Code Playgroud)
效率取决于编译器的优化器.例如,循环可以将size成员变量增加N次.
另一个较新的问题(与该问题重复)具有答案,看起来与此处的要求完全相同。这是(v3)的副本,以供快速参考:
一个众所周知的问题是,即使为明确也不能关闭初始化
std::vector。人们通常实现自己
pod_vector<>的元素,而不对元素进行任何初始化。另一种方法是创建与char布局兼容的类型,其构造函数不执行任何操作:
Run Code Online (Sandbox Code Playgroud)struct NoInitChar { char value; NoInitChar() { // do nothing static_assert(sizeof *this == sizeof value, "invalid size"); static_assert(__alignof *this == __alignof value, "invalid alignment"); } }; int main() { std::vector<NoInitChar> v; v.resize(10); // calls NoInitChar() which does not initialize // Look ma, no reinterpret_cast<>! char* beg = &v.front().value; char* end = beg + v.size(); }
| 归档时间: |
|
| 查看次数: |
13570 次 |
| 最近记录: |