考虑具有相同实体的两个迭代器方法:
public static IEnumerable<int> It1() {
...
}
public static IEnumerator<int> It2() {
...
}
Run Code Online (Sandbox Code Playgroud)
呼叫It2与呼叫有It1.GetEnumerator()什么不同吗?
是否有充分的理由将迭代器定义为IEnumerator<T>结束IEnumerable<T>?我能想到的唯一一个就是你实施的时候IEnumerable<T>.GetEnumerator().
编辑:通过迭代器方法我的意思是使用yield return和yield break构造的方法.
我知道这些问题之前有各种各样的问题,但这有点不同.
我有一个包含std :: map的类.虽然我希望在类中使用映射用于其他目的,但在外部我想要将迭代器适配器暴露给映射内的值(即std :: pair中的第二项).
例如在python中我可能会这样做:
def __iter__(self):
return self._dict.itervalues()
Run Code Online (Sandbox Code Playgroud)
我如何在c ++中执行此操作,将实现隐藏在类中?
谢谢,
担
我今天早上正在使用一些C#代码,我有类似的东西:
foreach(DataRow row in MyMethod.GetDataTable().Rows) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
所以,由于我没有完全理解语言框架,我想知道每次迭代完成后是否调用GetDataTable(),或者只是调用一次并且结果数据(可能是Rows)保存在内存循环通过它.无论如何,我宣布了一个新的集合来保存它并从那里工作......
我添加了一个新变量,所以我做了:
DataRowCollection rowCollection = MyMethod.GetDataTable().Rows;
foreach(DataRow row in rowCollection) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
但我不太确定这是否有必要.
提前致谢.
我希望以一种易于理解的形式了解该声明的所有内容yield.
我已经阅读了关于yield实现迭代器模式时的语句及其简易性.但是,大部分都非常干燥.我想深入研究微软如何处理收益率.
另外,你什么时候使用收益率突破?
我有一个X类,我在这里提供了一个片段:
class X {
public:
template <typename Iter>
X(Iter begin, Iter end) : mVec(begin, end) {}
private:
vector<Y> const mVec;
};
Run Code Online (Sandbox Code Playgroud)
我现在想为这个类添加一个新的连接构造函数,如:
template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) : mVec(???) { ??? }
Run Code Online (Sandbox Code Playgroud)
这样的构造函数会将两个范围[begin1,end1]和[begin2,end2]连接到mVec中.挑战是
1)我想在mVec上保留const,因此在X的其他方法中它被认为是常量.
2)如果可能的话,我想避免不必要的副本.也就是说,一种解决方案是使用静态方法将非const临时构造到范围1,插入范围2并返回它,然后将连接构造函数定义为
template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2)
: mVec(concatenate(begin1, end1, begin2, end2)) { }
Run Code Online (Sandbox Code Playgroud)
但我认为,这至少会复制一次所有的价值.
我想设计一个类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) 有一个 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++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的意思?