为什么range的算法与std的迭代器不兼容?

时间:2018-09-21 02:05:09

标签: c++ iterator c++-concepts c++20 range-v3

 func observeStars() {

    guard let toId = users?.id else {
        return }
    let placesRef = Database.database().reference().child("Review")

    placesRef.observeSingleEvent(of: .value, with: { snapshot in

        for child in snapshot.children {

            let placeSnap = child as! DataSnapshot
            let ratingsSnap = placeSnap.childSnapshot(forPath: "STAR")
            print(ratingsSnap)
            let count = ratingsSnap.childrenCount
            var total: Double = 0.0
            for child in ratingsSnap.children {
                print(child)
                let snap = child as! DataSnapshot
                let val = snap.value as! Double
                total += val
            }
            let average = total/Double(count)
            print(average)

        }
    })
}

问题显示在上面的代码中。我使用ranges-v3-0.3.7

对我来说,通用算法{ "Review" : { "75YFHCGX8WQyP3qlyvQKNohgCvQ2" : { "-LM9OW1eLcS9yr3JZxP5" : { "FROM" : "AV4RFwIlSNdnryfPPCl6SfLOzBZ2", "STAR" : 3, "TIMESTAMP" : 1.5366990112576609E9, "TO" : "75YFHCGX8WQyP3qlyvQKNohgCvQ2" }, "-LM9OoyD8A8HWZ387Ln9" : { "FROM" : "MAc9ouJnAacHddqDMRet3K9SkZq1", "STAR" : 2, "TIMESTAMP" : 1.5366990928939629E9, "TO" : "75YFHCGX8WQyP3qlyvQKNohgCvQ2" } }, "MAc9ouJnAacHddqDMRet3K9SkZq1" : { "-LM9Oa1zGbRjdCERwoDX" : { "FROM" : "AV4RFwIlSNdnryfPPCl6SfLOzBZ2", "STAR" : 4, "TIMESTAMP" : 1.536699031758939E9, "TO" : "MAc9ouJnAacHddqDMRet3K9SkZq1" } } 不需要关心目标迭代器的类型,只要它满足输出迭代器的要求即可。

如果是这样,为什么range的算法与std的迭代器不兼容?

1 个答案:

答案 0 :(得分:16)

  

对我来说,通用算法copy不需要关心目标迭代器的类型,只要它满足输出迭代器的要求即可。

这是正确的。并非ranges::copy以某种方式识别ranges::ostream_iterator而不是std::ostream_iterator。正是Ranges对OutputIterator 是什么有了一个精确的概念,例如ranges::ostream_iterator可以对OutputIterator进行建模,而std::ostream_iterator 则不能

具体来说,ranges::copy()需要WeaklyIncrementable<O>来完善SemiRegular<O>,而ranges::ostream_iterator需要DefaultConstructiblestd::ostream_iterator是默认可构造的,但P0896不是。

因此失败。


Link中,基于范围的copy()算法的输出迭代器确实需要WeaklyIncrementable(因此需要DefaultConstructible),但还要通过添加默认值来解决此不匹配问题std::ostream_iterator的构造函数(请参见第70页)。


请注意,范围-v3 /范围TS /范围提议概念OutputIterator与标准库的OutputIterator现有概念是分开的。 std::ostream_iterator不会为前者建模,但它会(em)为后者建模-因此,今天将std::copystd::ostream_iterator一起使用是非常好的。在P0896之后,将ranges::copystd::ostream_iterator一起使用也可以-因为建议对std::ostream_iterator进行更改。