在基于范围的 for 循环中设置矢量元素
Setting vector elements in range-based for loop
在分配给动态分配的std::vector
的元素时,我遇到了我认为基于 c++11 范围的 for 循环的奇怪行为。我有以下代码:
int arraySize = 1000;
std::string fname = "aFileWithLoadsOfNumbers.bin";
CTdata = new std::vector<short int>(arraySize, 0);
std::ifstream dataInput(fname.c_str(), std::ios::binary);
if(dataInput.is_open()
{
std::cout << "File opened sucessfully" << std::endl;
for(auto n: *CTdata)
{
dataInput.read(reinterpret_cast<char*>(&n), sizeof(short int));
// If I do "cout << n << endl;" here, I get sensible results
}
// However, if I do something like "cout << CTdata->at(500) << endl;" here, I get 0
}
else
{
std::cerr << "Failed to open file." << std::endl;
}
如果我将循环更改为更传统的for(int i=0; i<arraySize; i++)
并使用&CTdata->at(i)
代替读取函数中的&n
,事情就会如我预期的那样进行。
我错过了什么?
更改此循环语句
for(auto n: *CTdata)
自
for(auto &n : *CTdata)
也就是说,您必须使用对向量元素的引用。
你必须写
for( auto& n : *CTdata )
因为auto n
意味着short int n
当你需要short int& n
.我建议您阅读差异Beetween Decltype和Auto。
循环失败的原因是按值引用向量元素。但是,在这种情况下,您可以完全消除循环:
dataInput.read(reinterpret_cast<char*>(CTdata->data()), arraySize*sizeof(short int));
这会在一次调用中将内容读入向量。
弗拉德的回答完美地回答了你的问题。
但是,请考虑一下。与其从一开始就用零填充数组,不如调用 vector<>::reserve()
,它预先分配您的后备缓冲区,而无需更改矢量的前向部分。
然后,您可以像往常一样调用vector<>::push_back()
,而不会对性能造成任何影响,同时仍保持源代码中的逻辑清晰。来自 C# 背景,像这样循环使用矢量对我来说似乎是可憎的,更不用说你为每个元素设置了两次。另外,如果你的元素生成在任何时候失败,你会有一堆本来就不应该存在的零。
相关文章:
- 具有Qt事件循环的可移植通用共享库设置
- 对于完成布尔值设置为 true 后未停止的循环
- 循环中的变量被设置为下一个数组的元素始终具有相同的内存地址?
- 是否可以为一个循环设置多个条件
- 循环 std::由索引设置
- 第二个 while 循环未运行,将值设置为 "nan"
- C++ if 语句将条件设置为 true 和循环中的 OR-ing 条件之间的行为差异
- while 循环是否在设置标志的情况下运行多次?
- 有没有办法在C++中将偏移量设置为基于范围的 for 循环?
- 循环以使用设置模板类将所有 26 个字母添加到 s 中
- 尝试在自定义 QT 创建器文本编辑器中创建查找和替换循环.我似乎无法设置光标位置
- 在循环中设置指向 int 值的指针
- 如何将布尔矩阵的每个元素设置为false而不循环
- 如何使用Boost Graph库使用循环中的循环设置相同的边缘重量
- 一个线程设置成员,而另一个循环上方 - 是此螺纹 - 不安全
- 如何在没有循环的字节中设置位
- 对于循环设置变量为条件
- C++ 如何在地图中循环设置
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- Arduino循环/设置问题