如何在VB.NET中实现迭代器模式,它没有yield关键字?
我有一个带有大量控件的表单,我想迭代某个面板上的所有控件并启用/禁用它们.
我试过这个:
var component: TComponent;
begin
for component in myPanel do
(component as TControl).Enabled := Value;
end;
Run Code Online (Sandbox Code Playgroud)
但那没有做任何事.原来所有组件都在表单的组件集合中,而不是它们的父对象.那么有谁知道是否有任何方法可以获得控件内的所有控件?(除了像这样的丑陋的解决方法,这是我最终必须做的):
var component: TComponent;
begin
for component in myPanel do
if (component is TControl) and (TControl(component).parent = myPanel) then
TControl(component).Enabled := Value;
end;
Run Code Online (Sandbox Code Playgroud)
有人请告诉我有更好的方法......
我知道boost中的范围迭代器,对于这个引用,似乎应该有一种简单的方法来做我想要的,但这对我来说并不明显.
假设我想表示一个数字范围,0到100(包括或不包括),比方说range(0,100).我想做的事情如下:
for_each(range<int>(0,100).begin(), range<int>(0,100).end(), do_something);
Run Code Online (Sandbox Code Playgroud)
哪里do_something是仿函数.这个迭代器不应该有一个下面的向量或类似的东西的开销,但只提供一个整数序列.这是否可以通过boost中的范围实现来实现?可以使用普通的标准STL迭代器吗?
我在一个数组中有一个主机列表,它们代表可用于执行特定工作的服务器.目前我只是通过列表迭代查找并与主机建立通信以检查其不忙.如果没有,我会发一份工作.这种方法往往意味着列表中的第一个主机容易变得热,并且负载与其他可用主机不能正确平衡.
在伪代码..
for (Host h : hosts) {
//checkstatus
if status == job accepted break;
}
Run Code Online (Sandbox Code Playgroud)
我想在主机之间正确平衡这个负载,即第一次使用主机,第二次使用方法主机2.只是想知道最优雅的解决方案是?
谢谢你
在我正在实现的算法中,我需要操作struct T的std :: list .T持有对T的另一个实例的引用,但是这个引用也可以是"未分配的".起初,我想使用一个指针来保存这个引用,但是使用迭代器可以更容易地从列表中删除.
我的问题是:如何用迭代器表示等效于空指针?
我读通用解决方案是使用myList.end(),但在我的情况下,我需要测试迭代器是否为"null",并且我可以在存储迭代器的时刻之间添加或删除元素我从列表中删除它的那一刻......我应该让迭代器指向包含"null"元素的已知列表吗?还是有更优雅的解决方案?
我记得曾经看到过使用迭代器将一个完整的二进制文件读入一个向量的巧妙方法.它看起来像这样:
#include <fstream>
#include <ios>
#include <iostream>
#include <vector>
using namespace std;
int main() {
ifstream source("myfile.dat", ios::in | ios::binary);
vector<char> data(istream_iterator(source), ???);
// do stuff with data
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们的想法是vector通过传递指定整个流的输入迭代器来使用's iterator范围构造函数.问题是我不确定要为最终迭代器传递什么.
你如何创建istream_iterator一个文件的结尾?我完全记错了这个成语吗?
可能重复:
从迭代器获取const_iterator
我想写一元函数返回相应的const_iterator从iterator
template <class Iterator>
struct get_const_iterator
{
typedef ??? type;
};
Run Code Online (Sandbox Code Playgroud)
get_const_iterator<int*>::type 一定是 const int*get_const_iterator<const int*>::type 一定是 const int* get_const_iterator<int* const>::type必须是const int*或const int* const,我不在乎get_const_iterator<std::list<char>::iterator>::type 一定是 std::list<char>::const_iterator等等
可以使用iterator_traits或不使用它们吗?
编辑:我们假设如果2个容器具有相同的iterator类型,那么它们也具有相同的const_iterator类型.我认为这是一个合理的假设,虽然理论上并不完全正确.
当循环遍历一个结构片段时,我得到的值是一个引用(这很好),但是在某些情况下,必须var像(*var)在很多地方一样编写它是很烦人的.
有没有更好的方法来避免重新声明变量?
fn my_fn(slice: &[MyStruct]) {
for var in slice {
let var = *var; // <-- how to avoid this?
// Without the line above, errors in comments occur:
other_fn(var); // <-- expected struct `MyStruct`, found reference
if var != var.other {
// ^^ trait `&MyStruct: std::cmp::PartialEq<MyStruct>>` not satisfied
foo();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅:实际错误输出(更加神秘).
假设我有一个iterator当从中消耗元素时执行一些副作用的操作,例如修改列表。如果我定义一个list l和call l.extend(iterator),是否保证在迭代器中的元素被消耗时,extend将元素l逐个推入一个元素,而不是保留在缓冲区中然后一次推入所有元素?
我在计算机上使用Python 3.7进行了快速测试,list.extend基于该测试似乎很懒。(请参见下面的代码。)这是否由规范保证,如果可以,则在规范中提到了什么?
(此外,请随时批评我,并说“这不是Python风格的,您这个傻瓜!”-尽管如果您也想回答我这个问题也回答了我,我将不胜感激。自己的好奇心。)
假设我定义了一个迭代器,该迭代器会在运行时推送到列表中:
l = []
def iterator(k):
for i in range(5):
print([j in k for j in range(5)])
yield i
l.extend(iterator(l))
Run Code Online (Sandbox Code Playgroud)
以下是非延迟(即缓冲)与延迟可能extend实现的示例:
def extend_nonlazy(l, iterator):
l += list(iterator)
def extend_lazy(l, iterator):
for i in iterator:
l.append(i)
Run Code Online (Sandbox Code Playgroud)
这是当我运行的两个已知实现时发生的情况extend。
非懒惰:
l = []
extend_nonlazy(l, iterator(l))
Run Code Online (Sandbox Code Playgroud)
# output
[False, False, False, False, False] …Run Code Online (Sandbox Code Playgroud)