假设我们需要迭代一个容器。传统的 for 循环看起来像这样:
for (auto it = container.begin(), end = container.end();
it != end;
++it)
{
doStuff(*it);
}
虽然基于范围的 for 看起来像这样:
for (auto& element : container)
{
doStuff(element);
}
现在,在开发的某个阶段,我们意识到出于某种原因,我们需要在这些循环迭代中增加一些其他东西。
需要增加的可能是各种各样的东西。例如,如果我们将相关数据存储在其他相同大小的容器中,我们可能也需要在迭代过程中将迭代器递增到这些容器(尽管我希望标准库的 future 版本将允许我们做更多的事情)表达方式,通过结构化绑定(bind)和标准版本的 boost::range::combine 或其他东西)。
在下文中,为了简单起见,我们假设我们要为每个元素分配一个 ID,因此需要递增的只是一个计数器。
传统的循环现在看起来像这样:
unsigned int elementID = 0u;
for (auto it = container.begin(), end = container.end();
it != end;
++it, ++elementID)
{
doStuff(*it, elementID);
}
几乎不需要更改任何内容,在 ++it 之后添加 ++elementID 可确保无论每次迭代后发生什么,计数器都会递增。即使另一个程序员要修改循环体,比如说,在某些条件下通过 continue 提前进入下一次迭代,他们也不会有忘记递增计数器或类似的东西的风险那个。
现在,据我所知,使用基于范围的 for 进行递增的唯一方法是执行如下操作:
unsigned int elementID = 0u;
for (auto& element : container)
{
doStuff(element, elementID);
++elementID;
}
也就是说,将增量放在循环体内。
这对于 elementID 的表现力较低(即,如果代码主体很长,阅读代码的人不会一眼就看出我们正在遍历 elementID 也是),它不能提供我上面提到的保证,所以它也容易出错。
真的没有其他方法可以用基于范围的 for 来实现吗?或者有没有一种方法可以按照 for(auto& element : container;++elementID){...} 的方式编写我根本不知道的内容?
在人们回答后编辑
Nevin 建议使用 boost 的 BOOST_SCOPE_EXIT_ALL,就非本地解决方案而言,它最接近我的想法。
我不确定实际的实现,但我猜这依赖于 lambda 和析构函数。我写这个是为了测试它:
template <typename T>
class ScopeExitManager
{
public:
ScopeExitManager(T const& functionToRunOnExit) : _functionToRunOnExit(functionToRunOnExit)
{
}
~ScopeExitManager()
{
_functionToRunOnExit();
}
private:
T _functionToRunOnExit;
};
template <typename T>
ScopeExitManager<T> runOnScopeExit(T const& functionToRunOnExit)
{
return {functionToRunOnExit};
}
这让我可以按照以下方式写一些东西:
unsigned int elementID = 0u;
for (auto& element : container)
{
// Always at the beginning of the loop
auto scopeExitManager = runOnScopeExit([&elementID](){++elementID;});
// Actual body of the loop
doStuff(element, elementID);
}
它具有表现力并保证 elementID 将递增。这太棒了!
最佳答案
实现此目的的另一种方法是使用类似 Boost.ScopeExit 的东西,如:
unsigned int elementID = 0u;
for (auto& element : container)
{
BOOST_SCOPE_EXIT_ALL(&) { ++elementID; };
doStuff(element, elementID);
}
关于c++ - 基于范围的 for 和其他增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56604377/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit