std::copy_n 不会更改目标矢量大小
std::copy_n doesn't change destination vector size
如果我为向量保留一些空间,然后我用std::copy_n()
复制其中的一些值,我会正确复制并可访问的值,但向量的大小仍然为零。这是预期的行为吗?我是否应该调整矢量的大小,即使它没有那么高效?
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<double> src, dest;
for(double x = 0.0; x < 100.0; ++x)
src.push_back(x);
dest.reserve(src.size());
std::copy_n(src.cbegin(), src.size(), dest.begin());
std::cout << "src.size() = " << src.size() << std::endl;
std::cout << "dest.size() = " << dest.size() << std::endl;
for(size_t i = 0; i < src.size(); ++i)
std::cout << dest[i] << " ";
}
测试的编译器:clang,gcc,Visual C++
但是向量的大小仍然为零
std::copy_n
不会更改容器的大小,只需复制值并单步执行迭代器;它甚至没有任何关于容器的信息。因此,代码具有未定义的行为,即使它看起来工作正常。
我是否应该调整矢量的大小,即使它没有那么高效?
是的,您可以使用std::vector::resize
而不是std::vector::reserve
来解决问题。正如您可能已经想到的那样,这意味着所有元素都将首先由resize
构造,然后由copy_n
分配。
您可以使用 std::back_inserter,它将通过调用容器的 push_back()
成员函数(即直接构造元素(在容器的末尾附加元素,从而增加容器的大小。
dest.reserve(src.size());
std::copy_n(src.cbegin(), src.size(), std::back_inserter(dest));
关于标准库算法,要记住的关键是它们在范围上运行,而不是在容器上运行。容器是创建范围的方法之一,但它们不是唯一的方法。将结果写入范围的算法假定它们正在写入有效位置;它们不会也不能扩展它们要写入的范围。
因此,当您调用std::copy_n
时,您必须提供一个足够大的范围来保存结果。这意味着使用 dest.resize(src.size());
设置范围,而不仅仅是使用 dest.reserve(std.size());
分配内存。
或者,可以通过使用 std::back_inserter(dest)
而不是 dest.begin()
调用算法来提供一个知道它已附加到容器并需要调整大小的范围。
std::vector 具有大小和容量。它保留了一些比必要的空间更多的空间,以使插入速度更快。保留允许您指定该容量,而调整大小会更改矢量的实际大小。
在调用 reserve
后,您的dest
分配了内存来存储元素,但它不调用构造函数,它实际上是空的,因此您的代码会导致 UB。使用resize
实际创建这些元素,然后就可以了。
dest.resize(src.size());
std::copy_n(src.cbegin(), src.size(), dest.begin());
std::cout << "src.size() = " << src.size() << std::endl;
std::cout << "dest.size() = " << dest.size() << std::endl;
for(size_t i = 0; i < src.size(); ++i)
std::cout << dest[i] << " ";
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++A*算法并不总是在路径中具有目标节点
- std::filesystem::copy throws filesystem_error
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 为测试目标创建具有不同源文件夹的文件
- 使用源向量作为目标
- 是否可以用C++/WinRT将windows 10.0.14393作为目标
- 如何在 Boost.Asio 中使用 Zero-copy sendmsg/receive
- 在 CMake 中为每个目标设置编译器/链接器标志
- qmake:检测目标位宽(32 位或 64 位)
- 如何在 CMake 中对目标依赖项进行分组?
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 如何为包含头文件的目标编写生成文件?
- 线性优化目标函数中的绝对值
- 制作文件:没有规则来制定目标:如何设置正确的规则?
- 字符串函数在目标C++上运行时C++返回空
- 如何定义自定义生成配置类型,其中通常是.exe的目标改为 DLL
- 请求最简单的 OpenMP 目标 GPU 示例
- LLVM 编译:目标的配方 '../lib/IR/Release+Asserts/Intrinsics.gen.tmp' failed
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?