C++17 引入了 ContiguousIterator 的概念 http://en.cppreference.com/w/cpp/iterator .
然而,似乎没有计划拥有 contiguous_iterator_tag (以同样的方式我们现在有 random_access_iterator_tag )由 std::iterator_traits<It>::iterator_category 报告.
为什么是 contiguous_iterator_tag不见了?
是否有确定迭代器是否连续的常规协议(protocol)? 还是编译时测试?
过去我提到容器如果有.data()转换为指向 ::value 的指针的成员输入有.size()成员可转换为指针差异,那么应该假设容器是连续的,但我无法提取迭代器的类似功能。
一个解决方案可能是同时拥有一个 data连续迭代器的函数。
如果&(it[n]) == (&(*it)) + n,当然连续概念有效。 , 对于所有 n ,但在编译时无法检查。
编辑:我发现这个视频将其置于更广泛的 C++ 概念背景中。 CppCon 2016: "Building and Extending the Iterator Hierarchy in a Modern, Multicore World"帕特里克·尼齐尔斯基。该解决方案使用概念(Lite),但最终的想法是连续迭代器应该实现 pointer_from函数(与我的 data(...) 函数相同)。
结论是,概念将有助于将理论形式化,但它们并不神奇,因为某人、某处将在连续的迭代器上定义新的特别命名的函数。
该演讲概括为分段迭代器(具有相应的函数 segment 和 local ),不幸的是它没有提及跨步指针。
2020 年编辑:
标准现在有
struct contiguous_iterator_tag: public random_access_iterator_tag { };
最佳答案
原因在 N4284 中给出。 ,这是被采用的连续迭代器提案的版本:
This paper introduces the term "contiguous iterator" as a refinement of random-access iterator, without introducing a corresponding
contiguous_iterator_tag, which was found to break code during the Issaquah discussions of Nevin Liber's paper N3884 "Contiguous Iterators: A Refinement of Random Access Iterators".
某些代码被破坏,因为它假定 std::random_access_iterator 无法细化,并对其进行了明确的检查。基本上它破坏了不依赖多态性来检查迭代器类别的坏代码,但它仍然破坏了代码,所以std::contiguous_iterator_tag已从提案中删除。
另外, std::reverse_iterator 还有一个问题。 -like 类:反向连续迭代器不能是连续迭代器,而是常规随机访问迭代器。 std::reverse_iterator 可以解决此问题。 ,但更多用户定义的迭代器包装器在复制迭代器类别的同时扩充迭代器可能会撒谎或停止正常工作(例如 Boost 迭代器适配器)。
由于我上面的原始答案,std::contiguous_iterator_tag在 Ranges TS 中被带回,然后在 C++20 中采用。为了避免上述问题,std::iterator_traits<T>::iterator_category 的行为没有改变。相反, std::iterator_traits 的用户特化现在可以定义一个额外的iterator_concept成员类型别名,允许别名 std::contiguous_iterator_tag或以前的迭代器标签。标准组件已相应更新,以便将指针和适当的迭代器标记为连续的迭代器。
标准定义了一个仅用于说明的ITER_CONCEPT(Iter),给定一个迭代器类型Iter , 将别名 std::iterator_traits<Iter>::iterator_concept如果它存在并且std::iterator_traits<Iter>::iterator_category否则。没有等效的标准面向用户的类型特征,但 ITER_CONCEPT 被新的迭代器概念使用。这是一个强烈的提示,您应该使用这些迭代器概念而不是旧式标签调度来实现其行为取决于迭代器类别的新函数。上述概念可用作 bool 特征,因此您可以简单地检查迭代器是否为连续迭代器,如下所示:
static_assert(std::contiguous_iterator<Iter>);
std::contiguous_iterator 因此,您应该使用 C++20 概念来检测给定的迭代器是随机访问迭代器(它也有对应的范围: std::contiguous_range )。值得注意的是std::contiguous_iterator除了要求 ITER_CONCEPT 匹配 std::contiguous_iterator_tag 之外,还有一些额外的限制。 : 最值得注意的是它需要 std::to_address(it) 成为返回原始指针类型的有效表达式。 std::to_address是一个小型实用函数,旨在避免在尝试检索连续迭代器指向的地址时可能发生的一些陷阱 - 您可以在 Helpful pointers for ContiguousIterator 中阅读有关它解决的问题的更多信息.
关于实现 ITER_CONCEPT:只有在 you are the owner of std::iterator_traits 的情况下才能实现标准中描述的 ITER_CONCEPT,这毫无值(value)。因为它需要检测 std::iterator_traits 的主实例化是否被使用了。
关于c++ - 连续迭代器检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42851957/
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题
我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe