我正在玩 C++ 的建议 2d 图形库,我从这里获得的旧实现https://github.com/cristianadam/io2d,我试图在显示表面上渲染图像表面,我将其加载到向量中使用 std::copy 算法的无符号字符
auto loadimg(std::ifstream &file) {
std::vector<unsigned char> img_data{};
std::copy(std::istream_iterator<unsigned char>(file) ,
std::istream_iterator<unsigned char>(), img_data.begin());
return img_data;
}
Run Code Online (Sandbox Code Playgroud)
我也试过std::move了。
loadimg 函数的客户端是这样的
std::ifstream file("packagelevel.png");
img_surf.data(loadimg(file));
Run Code Online (Sandbox Code Playgroud)
尽管程序使用 Visual Studio 2017 编译。但我在调试时遇到错误“无法取消引用值初始化迭代器”,并且在 loadimg 返回语句中抛出了异常。我做错了什么?
当调用copy算法向量img_data为空时,当您向该向量写入数据时,您会遇到段错误。当您不知道要写入的输入数据的大小是多少时,您应该使用back_inserter将数据附加到向量中:
std::copy(std::istream_iterator<unsigned char>(file) ,
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));
Run Code Online (Sandbox Code Playgroud)
您在std::vector调用时提供了一个空作为目标std::copy(),因此它可能太小而无法容纳源数据,因此您会得到未定义的行为。要直接解决这个问题,您需要将 astd::back_inserter作为第三个参数传递给std::copy(). 这样,它会在std::vector复制到其中时附加到,从而确保它具有正确的大小 - 如底部的示例所示。
话虽如此,如果您想要的只是将文件的内容复制到 a 中,std::vector那么这将是一种常用且广泛推荐的模式,在这里使用第四个重载:
auto loadimg(std::ifstream &file) {
std::vector<unsigned char> img_data(
std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
return img_data;
}
Run Code Online (Sandbox Code Playgroud)
这是格式良好的,因为给构造函数(类型为std::istreambuf_iterator)的第一个参数满足 LegacyInputIterator。第二个参数是一个默认构造的std::istreambuf_iterator,它可以方便地用作end此流或任何此类流的迭代器。
| 归档时间: |
|
| 查看次数: |
11228 次 |
| 最近记录: |