我正在研究拟议的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;
}
我也尝试过std::move
。
loadimg函数的客户端是这样的
std::ifstream file("packagelevel.png");
img_surf.data(loadimg(file));
尽管该程序使用Visual Studio 2017进行编译。但是在调试时出现错误“无法取消引用值初始化迭代器” 并且在loadimg return语句上引发了异常。我在做什么错?
答案 0 :(得分:3)
当调用copy
算法向量img_data
为空时,将数据写入该向量时会出现段错误。当您不知道要写入的输入数据的大小时,应使用back_inserter
将数据追加到向量中:
std::copy(std::istream_iterator<unsigned char>(file) ,
std::istream_iterator<unsigned char>(), std::back_inserter(img_data));
答案 1 :(得分:3)
您在调用std::vector
时提供了一个空的std::copy()
作为目的地,因此它可能太小而无法容纳源数据,因此您会得到未定义的行为。要直接解决此问题,您需要将std::back_inserter
作为第三个参数传递给std::copy()
。这样,它将在复制到std::vector
时附加到std::vector
上,从而确保其大小正确-如示例here at the bottom所示。
话虽如此,如果您只想将文件的内容复制到auto loadimg(std::ifstream &file) {
std::vector<unsigned char> img_data(
std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
return img_data;
}
中,那么这将是一种普遍使用并被广泛推荐的模式,采用第四重载here:
std::istreambuf_iterator
这很好地构成了构造函数的第一个参数(类型为std::istreambuf_iterator
)satisfies LegacyInputIterator
。第二个参数是默认构造的getNow
,可以方便地标记此流或任何此类流中的最后一个迭代器。
答案 2 :(得分:0)
要使用std::copy
将元素插入向量的后面,您需要使用std::back_inserter
。如果不使用back_inserter
,则需要在调用std::copy
之前确保向量足够大。