我看到它提到的某个地方:
for ( itr = files.begin(); itr < files.end(); ++itr ) // WRONG
for ( itr = files.begin(); itr != files.end(); ++itr ) // ok
Run Code Online (Sandbox Code Playgroud)
为什么第一个表达式错了?我总是使用第一个表达式,并没有任何问题.
在C++中读取文件的常用方法是:
std::ifstream file("file.txt", std::ios::binary | std::ios::ate);
std::vector<char> data(file.tellg());
file.seekg(0, std::ios::beg);
file.read(data.data(), data.size());
Run Code Online (Sandbox Code Playgroud)
读取1.6 MB文件几乎是即时的.
但是最近,我发现了std :: istream_iterator并且想要尝试它以编码一个漂亮的单行方式来读取文件的内容.像这样:
std::vector<char> data(std::istream_iterator<char>(std::ifstream("file.txt", std::ios::binary)), std::istream_iterator<char>());
Run Code Online (Sandbox Code Playgroud)
代码很好,但很慢.读取相同的1.6 MB文件大约需要2/3秒.我知道它可能不是读取文件的最佳方式,但为什么它这么慢?
以经典方式读取文件是这样的(我只谈论读取函数):
当您使用istream_iterator读取文件时,它如下所示:
我必须承认,第二种方式效率不高,但它比第一种方式慢至少200倍,这怎么可能?
我认为性能杀手是重定位或插入,但我尝试创建一个完整的向量并调用std :: copy,它同样慢.
// also very slow:
std::vector<char> data2(1730608);
std::copy(std::istream_iterator<char>(std::ifstream("file.txt", std::ios::binary)), std::istream_iterator<char>(), data2.begin());
Run Code Online (Sandbox Code Playgroud) 六年前,我烧了几天试图追捕我完全确定的框架随机响应的地方.在精心追逐整个框架确保它全部使用相同的Random实例后,我继续追逐单步执行代码.这是高度重复的迭代自调用代码.更糟糕的是,该死的效果只会在完成大量迭代后出现.在+6小时之后,当我在javadoc中为HashSet.iterator()发现一行时,我终于处于智慧状态,表明它不能保证返回元素的顺序.然后我浏览了整个代码库,并用LinkedHashSet替换了所有HashSet实例.而且,我的框架正好向确定性生活迈进!哎呀!
我现在刚刚经历过同样的FREAKIN影响(至少这次只有3个小时).无论出于何种原因,我都错过了HashMap碰巧为其keySet()获得相同方式的细节.
这是关于这个主题的SO线程,虽然讨论从来没有完全回答我的问题:HashSet的迭代顺序
所以,我很好奇为什么会这样.鉴于我两次都有一个庞大的单线程java应用程序在完全相同的实例化/插入空间中使用完全相同的JVM参数(来自同一批处理文件的多次运行)在同一台计算机上运行,几乎没有其他任何运行,这可能会扰乱JVM使得HashSet和HashMap在经过大量迭代之后会表现得不可预测(并不是因为javadoc说不依赖于顺序而不一致)?
从源代码(java.util中的这些类的实现)或者你对JVM的了解(可能是某些GC影响内部java类在分配内部存储空间时获得非零内存的位置)的任何想法?
我正在尝试执行以下操作:
source = new int[10];
dest = new int[10];
std::copy( std::begin(source), std::end(source), std::begin(dest));
Run Code Online (Sandbox Code Playgroud)
但是,编译器报告以下错误.
copy.cpp:5434:14: error: ‘begin’ is not a member of ‘std’
copy.cpp:5434:44: error: ‘end’ is not a member of ‘std’
copy.cpp:5434:72: error: ‘begin’ is not a member of ‘std’
Run Code Online (Sandbox Code Playgroud)
我<iterator>在代码中包含了必需的标头.有人可以帮我这个吗?
我有一个关于如何在模板方式下使用迭代器的问题.
这是我想要做的一个例子,问题是,在for循环中如何初始化迭代器pp?
我读过类似的问题,但我不能完全理解,因为我是初学者.
迭代器类型应该在这个C++模板中应该是什么?
任何人都可以帮助并提供一些简单的解释吗?
#include <iostream>
#include <vector>
template <class T>
void my_print(std::vector<T> input){
for(std::vector<T>::iterator pp = input.begin(); pp != input.end(); ++pp)
std::cout << *pp << "\n";
}
int main(int argc,char* argv[]){
std::vector<int> aa(10,9);
my_print(aa);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误消息:
'std :: vector :: iterator'被解析为非类型,但实例化产生一个类型
假设我有一个可迭代对象(可以是映射(键)、列表、集合等),并且希望使用 Map() 将其转换为具有函数 f 的另一个可迭代对象。然而,我希望 f 在转换后仅在满足条件时返回一个值。
List<int> a = [1,2,3,4,5,6];
List<int> b = a.map((e) => (e % 2 == 0) ? e * 10 : null);
assert(b == [20,40,60]);
Run Code Online (Sandbox Code Playgroud)
然而,这会返回一个错误,就像map中带有mapEntry的任何类似的等效项一样,例如:
Map<int, String> a = {1:a, 2:b, 3:c, 4:d, 5:e, 6:f};
Map<int, String> b = a.map((k,v) => (k % 2 == 0) ? MapEntry(k*10,v) : null);
assert(b.keys.toList<int>() == [20,40,60]);
Run Code Online (Sandbox Code Playgroud)
当然,有一些方法可以通过牺牲效率和简洁性来解决这个问题,即在映射值之前或之后循环遍历它以过滤掉不需要的值。例如:
List<int> b = a.where((e) => e%2).map((e) => e * 10);
List<int> b = a.map((e) => e * 10).where((e) => e%2); …Run Code Online (Sandbox Code Playgroud) 当我使用迭代器时,我经常发现自己需要显式取消引用值。以下代码查找向量中所有元素对的总和:
extern crate itertools;
use crate::itertools::Itertools;
fn main() {
let x: Vec<i32> = (1..4).collect();
x.iter()
.combinations(2)
.map(|xi| xi.iter().map(|bar| **bar)
.sum::<i32>())
.for_each(|bar| println!("{:?}", bar));
}
Run Code Online (Sandbox Code Playgroud)
有没有比使用 a 更好的执行解除引用的方法map?
更好的是无需显式取消引用即可执行这些类型的操作。
在我的项目中,我想使用 C++ 和 STL 容器,但有一个问题,我必须包含用 ANSI C 编写的包含 C++ 的硬件供应商标头(并链接供应商库并使用一些还包括供应商标头的供应商 C 源)保留关键字,例如:vendor.h:
// Vendor header (read only)
struct Vendor_Export_Struct {
unsigned char* data;
};
struct Vendor_Export_Struct export; // <<< compilation error under C++
union Vendor_Union {
struct Vendor_Export_Struct export; // <<< compilation error under C++
};
Run Code Online (Sandbox Code Playgroud)
包含在 C++ 中的内容将在编译期间导致错误:在“导出”之前预期不合格的 id。所以我被迫使用纯 C 并考虑是否可以简单地将 STL 向量包装成这样的 C API(后面有 C++ 实现):
cvect.h :
typedef void* Vect_Type;
typedef void** Vect_Iterator_Type;
typedef void* Vect_Data_Type;
Vect_Type Vect_New();
void Vect_PushBack(Vect_Type v, Vect_Data_Type d);
Vect_Iterator_Type Vect_Begin(Vect_Type v);
Vect_Iterator_Type …Run Code Online (Sandbox Code Playgroud) 在我的 Python 3 脚本中,我试图根据输入组合来自三个不同列表的三个数字。如果列表大小相同,则zip. 但是,我希望能够为特定列表输入单个数字,并且脚本可以重复该数字,直到最长的列表完成。这可以通过zip_longest. 但是,fillvalue对于单独的列表,不可能有单独的填充值。
以这个简单的脚本为例:
from itertools import zip_longest
list1=[1]
list2=[4, 5, 6, 7, 8, 9]
list3=[2]
for l1, l2, l3 in zip_longest(list1, list2, list3):
print(l1, l2, l3)
Run Code Online (Sandbox Code Playgroud)
这是实际结果:
# 1 4 2
# None 5 None
# None 6 None
# None 7 None
# None 8 None
# None 9 None
Run Code Online (Sandbox Code Playgroud)
这将是我想要的结果:
# 1 4 2
# 1 5 2
# 1 6 2
# 1 7 2
# 1 …Run Code Online (Sandbox Code Playgroud) 我听说std::iterator在 C++17 中不推荐使用。
例如,像功能<algorithm>,更可能我们要使用begin()和end()它返回迭代器对象,如成员函数std::string,std::vector等等。
或者像基于范围的 for 循环,我们需要的地方begin()以及end()返回迭代器的地方。
因此,如果std::iterator基类被弃用,我们是否应该使用成员函数,如begin()和end()或使用 STL 中需要迭代器的其他函数?