标签: iterator

循环陷阱中的C++迭代器?

我看到它提到的某个地方:

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++ iterator stl

9
推荐指数
3
解决办法
559
查看次数

用C++读取文件的奇特方法:奇怪的性能问题

在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包含一个filebuf,其中包含文件中的数据块
  • read函数从filebuf 调用sgetn,它将chars从内部缓冲区逐个复制(无memcpy)到"data"的缓冲区
  • 当完全读取filebuf中的数据时,filebuf从文件中读取下一个块

当您使用istream_iterator读取文件时,它如下所示:

  • 向量调用*iterator来获取下一个char(这只是读取一个变量),将它添加到结尾并增加它自己的大小
  • 如果向量的已分配空间已满(不常发生),则执行重定位
  • 然后它调用++ iterator从流中读取下一个char(operator >> with char参数,当然只调用filebuf的sbumpc函数)
  • 最后它将迭代器与结束迭代器进行比较,这是通过比较两个指针来完成的

我必须承认,第二种方式效率不高,但它比第一种方式慢至少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)

c++ performance iterator file

9
推荐指数
1
解决办法
2246
查看次数

是什么导致java.util.HashSet和HashMap.keySet()类的iterator()稍微不可预测的排序?

六年前,我烧了几天试图追捕我完全确定的框架随机响应的地方.在精心追逐整个框架确保它全部使用相同的Random实例后,我继续追逐单步执行代码.这是高度重复的迭代自调用代码.更糟糕的是,该死的效果只会在完成大量迭代后出现.在+6小时之后,当我在javadoc中为HashSet.iterator()发现一行时,我终于处于智慧状态,表明它不能保证返回元素的顺序.然后我浏览了整个代码库,并用LinkedHashSet替换了所有HashSet实例.而且,我的框架正好向确定性生活迈进!哎呀!

我现在刚刚经历过同样的FREAKIN影响(至少这次只有3个小时).无论出于何种原因,我都错过了HashMap碰巧为其keySet()获得相同方式的细节.

这是关于这个主题的SO线程,虽然讨论从来没有完全回答我的问题:HashSet的迭代顺序

所以,我很好奇为什么会这样.鉴于我两次都有一个庞大的单线程java应用程序在完全相同的实例化/插入空间中使用完全相同的JVM参数(来自同一批处理文件的多次运行)在同一台计算机上运行,​​几乎没有其他任何运行,这可能会扰乱JVM使得HashSet和HashMap在经过大量迭代之后会表现得不可预测(并不是因为javadoc说不依赖于顺序而不一致)?

从源代码(java.util中的这些类的实现)或者你对JVM的了解(可能是某些GC影响内部java类在分配内部存储空间时获得非零内存的位置)的任何想法?

java iterator hashmap hashset

9
推荐指数
2
解决办法
3222
查看次数

C++ 11:错误:'begin'不是'std'的成员

我正在尝试执行以下操作:

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>在代码中包含了必需的标头.有人可以帮我这个吗?

c++ iterator compiler-errors std syntax-error

9
推荐指数
1
解决办法
2万
查看次数

带模板的c ++迭代器

我有一个关于如何在模板方式下使用迭代器的问题.
这是我想要做的一个例子,问题是,在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'被解析为非类型,但实例化产生一个类型

c++ iterator

9
推荐指数
1
解决办法
1万
查看次数

使用 Dart 有条件地返回 Map() 中的元素

假设我有一个可迭代对象(可以是映射(键)、列表、集合等),并且希望使用 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)

dictionary iterator arraylist filter dart

9
推荐指数
1
解决办法
1万
查看次数

What is the best way to dereference values within chains of iterators?

当我使用迭代器时,我经常发现自己需要显式取消引用值。以下代码查找向量中所有元素对的总和:

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

更好的是无需显式取消引用即可执行这些类型的操作。

iterator rust

9
推荐指数
1
解决办法
4880
查看次数

如何包装 std::vector 以在纯 C 中使用

在我的项目中,我想使用 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)

c c++ iterator stdvector

9
推荐指数
1
解决办法
476
查看次数

如何迭代多个不同长度的列表,但重复较短列表的最后一个值,直到完成最长列表?

在我的 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)

python iterator list python-3.x

9
推荐指数
2
解决办法
326
查看次数

如果不推荐使用 std::iterator ,我们还应该使用需要 std::iterator 的类或函数吗?

我听说std::iterator在 C++17 中不推荐使用。

例如,像功能<algorithm>,更可能我们要使用begin()end()它返回迭代器对象,如成员函数std::stringstd::vector等等。

或者像基于范围的 for 循环,我们需要的地方begin()以及end()返回迭代器的地方。

因此,如果std::iterator基类被弃用,我们是否应该使用成员函数,如begin()end()或使用 STL 中需要迭代器的其他函数?

c++ iterator for-loop c++17

9
推荐指数
2
解决办法
329
查看次数