在STL或boost中是否有C++等效的python Xrange生成器?
xrange基本上生成递增的数字,每次调用++运算符.构造函数是这样的:
xrange(first, last, increment)
Run Code Online (Sandbox Code Playgroud)
我希望通过每个使用boost来做这样的事情:
foreach(int i, xrange(N))
Run Code Online (Sandbox Code Playgroud)
我知道for循环.在我看来,他们是太多的样板.
谢谢
我想要这样做的主要原因是因为我使用语音文本软件,并且编程循环通常很难,即使使用代码完成.具有可显示的构造更有效.
许多循环从零开始并递增1,这是范围的默认值.我发现python构造更直观
for(int i = 0; i < N; ++i)
foreach(int i, range(N))
Run Code Online (Sandbox Code Playgroud)
需要将范围作为参数的函数:
Function(int start, int and, int inc);
function(xrange r);
Run Code Online (Sandbox Code Playgroud)
我理解语言之间的差异,但是如果python中的特定构造对我非常有用并且可以在C++中高效实现,我没有理由不使用它.对于每个构造,C++都是外来的,但是人们使用它.
我将我的实现放在页面底部以及示例用法.
在我的域中我使用多维数组,通常排名4张量.所以我经常会得到4个具有不同范围/增量的嵌套循环来计算规范化,索引等等.这些不一定是性能循环,我更关心正确性可读性和修改能力.
例如
int function(int ifirst, int ilast, int jfirst, int jlast, ...);
versus
int function(range irange, range jrange, ...);
Run Code Online (Sandbox Code Playgroud)
在上面,如果需要不同的strid,你必须传递更多的变量,修改循环等,最终你会得到大量的整数/几乎相同的循环.
foreach和range完全解决了我的问题.对普通C++程序员的熟悉程度并不高我的关注列表 - 问题领域是一个相当模糊,有很多元编程,SSE内在,生成代码.
今天PHP团队发布了PHP 5.5.0版本,其中包括对生成器的支持.阅读文档,我注意到它完全可以用数组做.
PHP团队生成器示例:
// Only PHP 5.5
function gen_one_to_three() {
for ($i = 1; $i <= 3; $i++) {
// Note that $i is preserved between yields.
yield $i;
}
}
$generator = gen_one_to_three();
foreach ($generator as $value) {
echo "$value\n";
}
Run Code Online (Sandbox Code Playgroud)
结果:
1
2
3
Run Code Online (Sandbox Code Playgroud)
但我可以使用数组做同样的事情.我仍然可以保持与早期版本的PHP兼容.
看看:
// Compatible with 4.4.9!
function gen_one_to_three() {
$results = array();
for ($i = 1; $i <= 3; $i++) {
$results[] = …Run Code Online (Sandbox Code Playgroud) 我有一个循环列表,我想look在达到之后跳过3个元素.在这个答案中提出了一些建议,但我没有充分利用它们:
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
for sing in song:
if sing == 'look':
print sing
continue
continue
continue
continue
print 'a' + sing
print sing
Run Code Online (Sandbox Code Playgroud)
continue当然四次是胡说八道,使用四次next()是行不通的.
输出应如下所示:
always
look
aside
of
life
Run Code Online (Sandbox Code Playgroud) 在我不断追求吸吮的过程中,我试图理解"收益"陈述,但我一直遇到同样的错误.
[someMethod]的主体不能是迭代器块,因为'System.Collections.Generic.List <AClass>'不是迭代器接口类型.
这是我遇到的代码:
foreach (XElement header in headersXml.Root.Elements()){
yield return (ParseHeader(header));
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我不能在迭代器中使用yield吗?那有什么意义呢?在这个例子中,它说它List<ProductMixHeader>不是迭代器接口类型.
ProductMixHeader是一个自定义类,但我想List是一个迭代器接口类型,不是吗?
- 编辑 -
感谢所有快速解答.
我知道这个问题不是全新的,同样的资源不断涌现.
事实证明我认为我可以List<AClass>作为返回类型返回,但由于List<T>不是懒惰,它不能.更改我的返回类型以IEnumerable<T>解决问题:D
一个有点相关的问题(不值得打开一个新线程):IEnumerable<T>如果我确定99%的情况我将要去.ToList(),它是否值得作为返回类型给出?性能影响是什么?
以下按预期工作:
d = [(1,2), (3,4)]
for k,v in d:
print "%s - %s" % (str(k), str(v))
Run Code Online (Sandbox Code Playgroud)
但这失败了:
d = collections.defaultdict(int)
d[1] = 2
d[3] = 4
for k,v in d:
print "%s - %s" % (str(k), str(v))
Run Code Online (Sandbox Code Playgroud)
附:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Run Code Online (Sandbox Code Playgroud)
为什么?我该如何解决?
比较来自不同容器的迭代器是否合法?
std::vector<int> foo;
std::vector<int> bar;
Run Code Online (Sandbox Code Playgroud)
表达式是否会foo.begin() == bar.begin()产生错误或未定义的行为?
(我正在编写一个自定义迭代器,并在实现时偶然发现了这个问题operator==.)
我需要找到向量中的max元素,所以我正在使用std::max_element,但我发现它是一个非常慢的函数,所以我编写了自己的版本并设法获得x3更好的性能,这里是代码:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/time.h>
double getRealTime()
{
struct timeval tv;
gettimeofday(&tv, 0);
return (double) tv.tv_sec + 1.0e-6 * (double) tv.tv_usec;
}
inline int my_max_element(const std::vector<int> &vec, int size)
{
auto it = vec.begin();
int max = *it++;
for (; it != vec.end(); it++)
{
if (*it > max)
{
max = *it;
}
}
return max;
}
int main()
{
const int size = 1 << 20;
std::vector<int> vec;
for (int …Run Code Online (Sandbox Code Playgroud) 我曾经认为,当遵循最佳实践时,C++的对象模型非常强大.
就在几分钟前,我意识到我以前没有过.
考虑以下代码:
class Foo
{
std::set<size_t> set;
std::vector<std::set<size_t>::iterator> vector;
// ...
// (assume every method ensures p always points to a valid element of s)
};
Run Code Online (Sandbox Code Playgroud)
我写了这样的代码.直到今天,我还没有看到它的问题.
但是,考虑到它更多,我意识到这个类非常破碎:
它的copy-constructor和copy-assignment 复制里面的迭代器vector,这意味着它们仍然会指向旧的 set!毕竟新的不是真正的副本!
换句话说,我必须手动实现copy-constructor,即使这个类没有管理任何资源(没有RAII)!
这令我惊讶.我以前从未遇到过这个问题,我也不知道有什么优雅的方法来解决它.关于它的思考多一点,在我看来,那拷贝构造是默认不安全的 -事实上,在我看来那类应该不会是在默认情况下拷贝,但因为他们的实例变量之间的任何一种耦合的风险再现默认副本- 构造函数无效.
迭代器是否从根本上说不安全?或者,默认情况下类是否真的不可复制?
我在下面想到的解决方案都是不可取的,因为它们不会让我利用自动生成的复制构造函数:
我刚刚了解了Java Collections Framework如何在链表中实现数据结构.根据我的理解,这Iterators是一种遍历数据结构(如列表)中的项目的方法.为什么使用这个界面?为什么这些方法hasNext(),next()而remove()不是直接编码到数据结构实现本身?
从Java网站:链接文本
public interface Iterator <E>
集合上的迭代器.Iterator取代了Java集合框架中的Enumeration.迭代器在两个方面与枚举不同:
此接口是Java Collections Framework的成员.
- 迭代器允许调用者在迭代期间使用定义良好的语义从底层集合中删除元素.
- 方法名称已得到改进.
我试着用Google搜索,似乎无法找到明确的答案.有人可以解释为什么Sun选择使用它们吗?是因为更好的设计?增加安全性?好的OO练习?
任何帮助将不胜感激.谢谢.
使用迭代器的代码看起来非常像带指针的代码.迭代器是一些模糊的类型(std::vector<int>::iterator例如).
我没有得到的是迭代器和指针是如何相互关联的 - 迭代器是指针周围的包装器,带有重载操作以前进到相邻元素,还是其他什么?