使用boost :: range的相邻适配器

时间:2018-06-28 06:16:22

标签: c++ stl iterator boost-range boost-iterators

我在问自己是否可以通过适配器(我称为scrollView.requestDisallowInterceptTouchEvent(true); 来扩展boost-range。该适配器基本上应该遍历adjacentAdaptorvector等中的所有相邻元素对。

我认为此功能在我的用例中非常有用,在我的用例中,我经常不得不遍历表示时间步长的列表。

最后一个for循环的输出应类似于:

list

仅包含一个元素或不包含任何元素的向量将不产生任何结果。

我尝试使用0 1 1 2 2 3 生成必要的子列表,但是后来我不知道boost::adaptors::sliced如何帮助我将两个子范围都压缩到一个。

我刚刚找到了使用boost::range的可能解决方案,但我真的不喜欢一个人必须编写大量的代码。另外,我还缺少boost::iteratorsfirst,而我不得不写笨拙的second。不幸的是,如果向量为空,程序就会崩溃!

get<>

我很高兴在这个问题上能获得任何帮助。

自己的部分解决方案

在推断出模板类型之后,我想出了一些相对有用的东西。

#include <vector>
#include <iostream>
#include <boost/range.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/zip_iterator.hpp>

int main()
{
        std::vector<int> v = { 0,1,2,3 };
        for (auto iter : v | boost::adaptors::sliced(0, v.size() - 1)) {
            std::cout << "First: " << iter << std::endl;
        }
        for (auto iter : v | boost::adaptors::sliced(1, v.size())) {
            std::cout << "Second: "<< iter << std::endl;
        }
        auto s = boost::iterators::make_zip_iterator(boost::make_tuple(v.begin(), v.begin() + 1));
        auto e = boost::iterators::make_zip_iterator(boost::make_tuple(v.end()-1, v.end()));
        for (auto iter : boost::make_iterator_range(s, e)) {
            std::cout << iter.get<0>() << " " << iter.get<1>() << std::endl;
        }
//          for (auto iter : v | adjacentAdaptor) {
//              std::cout << iter.first << " " << iter.second << std::endl;
//          }
}

不过,使用#include <vector> #include <iostream> #include <boost/range.hpp> #include <boost/range/algorithm/transform.hpp> #include <boost/range/adaptor/sliced.hpp> #include <boost/iterator.hpp> #include <boost/iterator/zip_iterator.hpp> template<typename T> using retHelperType = decltype(boost::iterators::make_zip_iterator(boost::make_tuple(T().begin(), T().begin() + 1))); template<typename T> using retType = decltype(boost::make_iterator_range(retHelperType<T>(), retHelperType<T>())); template<typename T> retType<T> adjacentIterator(T& v) { if (v.empty()) { auto s = boost::iterators::make_zip_iterator(boost::make_tuple(v.end(), v.end())); auto e = boost::iterators::make_zip_iterator(boost::make_tuple(v.end(), v.end())); return boost::make_iterator_range(s, e); } else { auto s = boost::iterators::make_zip_iterator(boost::make_tuple(v.begin(), std::next(v.begin()))); auto e = boost::iterators::make_zip_iterator(boost::make_tuple(std::prev(v.end()), v.end())); return boost::make_iterator_range(s, e); } } int main() { retType<std::vector<int>> x; std::vector<int> v = { }; for (auto iter : adjacentIterator(v)) { std::cout << iter.get<0>() << " " << iter.get<1>() << std::endl; } } first访问元素会更好,但是我不知道要实现这种行为。

0 个答案:

没有答案