我想设计一个类Foo来存储不同类型的各种数据并返回它们的迭代器。它应该是通用的,因此用户Foo不知道数据是如何存储的(Foo可能正在使用std::set或std::vector其他)。
我很想写一个这样的界面:
class Foo {
class FooImpl;
FooImpl* impl_;
public:
const Iterator<std::string>& GetStrings() const;
const Iterator<int>& GetInts() const;
};
Run Code Online (Sandbox Code Playgroud)
哪里Iterator有类似这样的东西(比如 .NET 中的迭代器):
template<class T>
class Iterator {
public:
const T& Value() const = 0;
bool Done() const = 0;
void Next() = 0;
};
Run Code Online (Sandbox Code Playgroud)
但我知道这种迭代器在C++中不是标准的,最好像STL那样使用迭代器,这样你就可以在它们上使用STL算法。
我怎样才能做到这一点?(我有需要iterator_traits吗?)
是否可以安全地寻找std::string::iterator给定位置?
std::string::iterator 有一个偏移访问运算符(运算符 []),但它存在于某些人定义为未定义行为的类别中,例如it + 3.
编辑:这里有一个类似的问题涉及迭代器重置。然而,下面接受的答案解决了嵌套迭代器的实际问题,并处理了一个容易错过的问题,即嵌套迭代器不会重置。
有没有办法在 python 中迭代迭代器两次?
在下面的示例代码中,我可以看到第二次迭代与第一次迭代在同一对象上运行,因此产生了奇怪的结果。将此与下面的 C# 进行对比,得到我想要的结果。
有什么办法可以做我想做的事。我想知道是否可以复制迭代器或“检索”它来自的函数,但也许有一种更简单的方法。(我知道我可以在下面的玩具示例中调用MyIter()两次,但如果我不知道迭代器来自哪里并且不是我想要的,那么这是没有用的!)。
def MyIter():
yield 1;
yield 2;
yield 3;
yield 4;
def PrintCombos(x):
for a in x:
for b in x:
print(a,"-",b);
PrintCombos(MyIter());
Run Code Online (Sandbox Code Playgroud)
给出
1 - 2
1 - 3
1 - 4
Run Code Online (Sandbox Code Playgroud)
对比:
static IEnumerable MyIter()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
static void PrintCombos(IEnumerable x)
{
foreach (var a in x)
foreach (var b in x)
Console.WriteLine(a + "-" …Run Code Online (Sandbox Code Playgroud) 使用如下所示的迭代器:
function* idMaker(){
let index = 0;
while(index < 3)
yield index++;
}
Run Code Online (Sandbox Code Playgroud)
如何确保根据情况提前停止发电机?
function* idMaker(){
let index = 0;
while(index < 3)
if (checker(index))
yield index++;
else
return;
}
Run Code Online (Sandbox Code Playgroud)
适合在发电机中使用吗?我应该使用break而不是yield break像 C# 中那样吗?
您能否提供一个 MDN 链接或讨论此问题的规范?
我正在编写一个定义__iter__and的类__len__,其中 的值__len__取决于__iter__. 我得到了一个有趣的RecursionError.
语言版本:Python 3.8.6、3.7.6。 示例仅用于说明错误。
在以下示例中,Iter.__len__()尝试解包self,将结果存储在 a 中list,然后尝试调用该list.__len__()列表上的内置函数以获取长度。
>>> class Iter:
... def __iter__(self):
... return range(5).__iter__()
... def __len__(self):
... return list.__len__([*self])
...
>>> len(Iter())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __len__
File "<stdin>", line 5, in __len__
File "<stdin>", line 5, in __len__
[Previous line repeated 993 more times] …Run Code Online (Sandbox Code Playgroud) 有一个 Scala Flink 应用程序,我在其中使用 Jackson 库解析 JSON。解析由自定义方法处理,它使用延迟启动概念来保持快速。
现在,无论出于何种原因,在 Flink 管道中进一步传递带有惰性值的模型会导致一些奇怪的错误,util.Iterator这是读取 JSON 的主干。我怀疑问题可能实际上来自Kryo但我不知道如何确认。值得注意的是,.toList在同一个(flink)中急切地初始化模型(使用)map修复了这个问题。但事实并非如此,我想进一步传递我的懒惰模型。
最后,我提供了一个带有演示代码的存储库,但我也想在 StackOverflow 中提供所有详细信息。
示例模型和解析定义:
case class Root(items: Collection[Data])
case class Data(data: Collection[Double])
def toRoot(node: JsonNode): Root = {
val data: util.Iterator[JsonNode] = if (node.hasNonNull("items")) node.get("items").elements() else node.elements()
val items: Collection[Data] = data.asScala.map(x => toData(x))
Root(items)
}
Run Code Online (Sandbox Code Playgroud)
JSON 数据类似于:
{
"items": [
{
"data": [
11.71476355252127,
48.342882259940176,
507.3,
11.714791605037252,
...
Run Code Online (Sandbox Code Playgroud)
并在一部map作品中完成所有工作:
env.fromCollection(Seq(input))
.map(i => flatten(read(i)))
.print()
Run Code Online (Sandbox Code Playgroud)
但进一步传递失败:
env.fromCollection(Seq(input))
.map(i …Run Code Online (Sandbox Code Playgroud) 在 C 中,我可以使用索引以嵌套方式可变地迭代数组。在 Rust 中,我几乎可以使用索引做同样的事情,但是如果我想使用迭代器而不是索引怎么办?
例如,以下代码段可以成功编译,因为两个借用都是不可变的:
let xs = [0, 1, 2];
for x in &xs {
for y in &xs {
println!("x={} y={}", *x, *y);
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果我想使用可变迭代器怎么办?
let mut xs = [0, 1, 2];
for x in &mut xs {
*x += 1;
for y in &mut xs {
*y += 1;
println!("x={} y={}", *x, *y);
}
}
Run Code Online (Sandbox Code Playgroud)
这导致:
error[E0499]: cannot borrow `xs` as mutable more than once at a time
Run Code Online (Sandbox Code Playgroud)
我理解需要引导对数据的写入访问,但我也想知道经验丰富的 Rust 用户如何仅使用迭代器来实现这一目标——假设索引仅用于教育目的。
C++20带来了更强大的迭代器系统,其中之一就是iterator_concept在iterator_category.
我发现C++20 中很多迭代器的iterator_concept和iterator_category是不一致的。以最著名iota_view的为例:
using R = decltype(views::iota(0));
static_assert(random_access_range<R>);
using I = ranges::iterator_t<R>;
static_assert(same_as<typename I::iterator_category, input_iterator_tag>);
static_assert(same_as<typename I::iterator_concept, random_access_iterator_tag>);
Run Code Online (Sandbox Code Playgroud)
虽然是Rmodels random_access_range,但iterator_category它的迭代器的the只是一个input_iterator_tag,与iterator_concept.
为什么C++20引入iterator_concept?它的目的是什么?如果我实现我自己的迭代器,我该如何界定iterator_concept和iterator_category正确?是否iterator_category仍然在C ++ 20的意思?
我想要一个可以接受固定值类型的任何范围/视图的函数。
int main()
{
std::array<std::pair<int, int>, 2> a{...};
std::array<std::pair<int, int>, 3> b{...};
generic_fun(a);
generic_fun(b);
};
Run Code Online (Sandbox Code Playgroud)
我当然可以
template <std::ranges::range R>
requires std::same_as<std::ranges::range_value_t<R>,std::pair<int,int>>
auto generic_fun(R range)
{
for(const auto& element : range)
return element.first;
}
Run Code Online (Sandbox Code Playgroud)
但 Visual Studio IDE 不知道element.
我期望范围库有类似的类型
template <typename T>
struct view
{
template <std::ranges::range R>
requires std::same_as<std::ranges::range_value_t<R>, T>
view(R);
T* begin() const;
T* end() const;
};
Run Code Online (Sandbox Code Playgroud)
这会给我 ide 支持
auto generic_fun(view<std::pair<int,int>> a)
{
for (const auto& b : a)
return b.first;
}
Run Code Online (Sandbox Code Playgroud)
为什么范围库中不存在这样的类型?定义一个抽象出除范围/迭代器的值类型之外的所有类型的类型在技术上是不可行的吗?或者没有人关心这样做,因为唯一的原因是 ide 支持? …
for...of当我中断循环时,是否可以循环迭代器的一部分而不关闭迭代器?
例子:
function* numbers(i=0){
while(true) yield i++;
}
let nums=numbers();
// this loop prints numbers from 0 to 3
for(const n of nums){
if(n>3) break;
console.log(n);
}
// this loop doesn't print anything because `nums` has already been closed
for(const n of nums){
if(n>10) break;
console.log(n);
}Run Code Online (Sandbox Code Playgroud)
我知道我可以通过自己的调用来遍历迭代器iterator.next()。但我想知道是否可以用for...of语法来做到这一点。
iterator ×10
c++ ×4
c++20 ×2
generator ×2
javascript ×2
python ×2
std-ranges ×2
apache-flink ×1
c# ×1
c++-concepts ×1
for-loop ×1
for-of-loop ×1
jackson ×1
kryo ×1
loops ×1
nested ×1
pimpl-idiom ×1
python-3.x ×1
range-v3 ×1
rust ×1
scala ×1
seek ×1
stl ×1
string ×1
yield ×1