如何创建隐藏多层向量并将其公开为单个范围的 Boost.Range?

2024-02-13

我有一个无法修改的遗留类层次结构。由于外部库的要求,我需要为 Line 和 Ring 定义 Boost.Range,其中两者仅在单次运行中公开点(即,对于 Line 和 Ring,它应该是点的 Boost.Range) 。

伪代码来说明:

Line l1 = Line{{1.0,2.0},{3.0,4.0},{5.0,6.0}} // init Line with three Points
Line l2 = Line{{7.0,8.0},{9.0,10.0},{11.0,12.0}} // init Line with three Points

auto lit = boost::begin(l1); // points to the Point{1.0,2.0}
++lit; // points to the Point{3.0,4.0}

Ring r1 = Ring{l1,l2} // init Ring with two Lines

auto rit = boost::begin(r1); // points to the Point{1.0,2.0}
++rit; // points to the Point{3.0,4.0}
++rit; // points to the Point{5.0,6.0}
++rit; // points to the Point{7.0,8.0}
++rit; // points to the Point{9.0,10.0}
// etc...

该线很容易,因为点是直接存储的(我已经使用 Boost.Range 成功完成了此操作看例子 http://www.boost.org/doc/libs/1_33_1/libs/range/doc/boost_range.html)。但是,我不知道如何使用 Ring 执行此操作,因为我需要直接获取每条线的点。

class Point 
{
  public:
  double x, y;
}

class Line
{
  public:
  std::vector<Point> points;
}

class Ring
{
  public:
  std::vector<Line> lines;
}

你需要extend http://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/extending.htmlBoost.Range 以便将 Ring 识别为有效范围。但在此之前,您需要定义一个自定义迭代器来展平vector< vector<T> >进入一维范围。

本示例使用Method 2 http://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/extending/method_2.html扩展 Boost.Range。它还使用boost::iterator_facade http://www.boost.org/doc/libs/release/libs/iterator/doc/iterator_facade.html为了方便编写自定义迭代器,并假设迭代器只需要支持前向遍历。

#include <iostream>
#include <vector>
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/foreach.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range.hpp>

struct Point
{
    Point(double x, double y) : x(x), y(y) {}
    double x, y;
};

struct Line {std::vector<Point> points;};

struct Ring {std::vector<Line> lines;};


/* Custom iterator type that flattens a 2D array into a 1D array */
template <class I, // Line iterator type
          class R  // Point reference type
         >
class RingIteratorImpl : public boost::iterator_facade<
        RingIteratorImpl<I,R>, Point, boost::forward_traversal_tag, R>
{
public:
    RingIteratorImpl() : lineIter_(0), pointIndex_(0) {}

    explicit RingIteratorImpl(I lineIter)
    :   lineIter_(lineIter), pointIndex_(0) {}

private:
    friend class boost::iterator_core_access;

    void increment()
    {
        ++pointIndex_;
        if (pointIndex_ >= lineIter_->points.size())
        {
            ++lineIter_;
            pointIndex_ = 0;
        }
    }

    bool equal(const RingIteratorImpl& other) const
    {
        return (lineIter_ == other.lineIter_) &&
               (pointIndex_ == other.pointIndex_);
    }

    R dereference() const {return lineIter_->points[pointIndex_];}

    I lineIter_;
    size_t pointIndex_;
};

typedef RingIteratorImpl<std::vector<Line>::iterator, Point&> RingIterator;
typedef RingIteratorImpl<std::vector<Line>::const_iterator, const Point&>
        ConstRingIterator;

namespace boost
{
    // Specialize metafunctions. We must include the range.hpp header.
    // We must open the 'boost' namespace.

    template <>
    struct range_mutable_iterator<Ring> { typedef RingIterator type; };

    template<>
    struct range_const_iterator<Ring> { typedef ConstRingIterator type; };

} // namespace 'boost'


// The required Range functions. These should be defined in the same namespace
// as Ring.

inline RingIterator range_begin(Ring& r)
    {return RingIterator(r.lines.begin());}

inline ConstRingIterator range_begin(const Ring& r)
    {return ConstRingIterator(r.lines.begin());}

inline RingIterator range_end(Ring& r)
    {return RingIterator(r.lines.end());}

inline ConstRingIterator range_end(const Ring& r)
    {return ConstRingIterator(r.lines.end());}


int main()
{
    Line l1, l2;
    Ring ring;

    {
        using namespace boost::assign; // bring 'operator+=()' into scope
        typedef Point P;
        l1.points += P(1.1,1.2), P(1.3,1.4), P(1.5,1.6);
        l2.points += P(2.1,2.2), P(2.3,2.4), P(2.5,2.6);
        ring.lines += l1, l2;
    }

    // Boost Foreach treats ring as a Boost Range.
    BOOST_FOREACH(Point p, ring)
    {
        std::cout << "(" << p.x << ", " << p.y << ") ";
    }
    std::cout << "\n";
}

我得到以下输出:

(1.1, 1.2) (1.3, 1.4) (1.5, 1.6) (2.1, 2.2) (2.3, 2.4) (2.5, 2.6) 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建隐藏多层向量并将其公开为单个范围的 Boost.Range? 的相关文章

  • 为什么这个 Web api 控制器不并发?

    我有一个 Web API 控制器 里面有以下方法 public string Tester Thread Sleep 2000 return OK 当我调用它 10 次 使用 Fiddler 时 我预计所有 10 次调用都会在大约 2 秒后
  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 现代 C++ 编译器是否能够在某些情况下避免调用 const 函数两次?

    例如 如果我有以下代码 class SomeDataProcessor public bool calc const SomeData d1 const SomeData d2 const private Some non mutable
  • 从复选框列表中选择循环生成的复选框中的一个复选框

    抱歉我的英语不好 在我的 ASP NET 网站上 我从 SQL 表导入软件列表 看起来像这样 但实际上要长得多 Microsoft Application Error Reporting br br Microsoft Applicatio
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • 无法注册时间触发的后台任务

    对于 Windows 8 应用程序 在 C Xaml 中 我尝试注册后台任务 很难说 但我想我的后台任务已正确注册 但是当我单击调试位置工具栏上的后台任务名称时 我的应用程序停止工作 没有任何消息 我查看了事件查看器上的日志 得到 具有入口
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • 即使没有异步,CallContext.LogicalGetData 也会恢复。为什么?

    我注意到CallContext LogicalSetData LogicalGetData不按照我期望的方式工作 内部设置的值async方法得到恢复即使没有异步或任何类型的线程切换 无论如何 这是一个简单的例子 using System u
  • 不同 C++ 文件中的相同类名

    如果两个 C 文件具有相同名称的类的不同定义 那么当它们被编译和链接时 即使没有警告也会抛出一些东西 例如 a cc class Student public std string foo return A void foo a Stude
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • C++ 对象用 new 创建,用 free() 销毁;这有多糟糕?

    我正在修改一个相对较大的 C 程序 不幸的是 并不总是清楚我之前的人使用的是 C 还是 C 语法 这是在一所大学的电气工程系 我们 EE 总是想用 C 来做所有事情 不幸的是 在这种情况下 人们实际上可以逃脱惩罚 但是 如果有人创建一个对象
  • 模板类中的无效数据类型生成编译时错误?

    我正在使用 C 创建一个字符串类 我希望该类仅接受数据类型 char 和 wchar t 并且我希望编译器在编译时使用 error 捕获任何无效数据类型 我不喜欢使用assert 我怎样才能做到这一点 您可以使用静态断言 促进提供一个 ht
  • C++:为什么 numeric_limits 对它不知道的类型起作用?

    我创建了自己的类型 没有任何比较器 也没有专门化std numeric limits 尽管如此 由于某种原因 std numeric limits
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • Visual Studio 2015 - Web 项目上缺少共享项目参考选项卡

    我从 MSDN 订阅升级到 Visual Studio 2015 因为我非常兴奋地阅读有关共享项目的信息 当我们想要做的只是重用代码时 不再需要在依赖项中管理 21382 个 nuget 包 所以我构建了一个测试共享项目 其中包含一些代码
  • 我可以使用 lambda 函数或 std::function 对象来代替函数指针吗?

    我有一个需要使用的库 它定义了以下内容 typedef void CallbackFunction const int i 并且有一个注册回调的函数 如下所示 void registerCallback CallbackFunction p

随机推荐

  • 如果客户端禁用了 Javascript,我该怎么办?

    我的网站严重依赖 Javascript 如果我将其关闭 我的网站就会看起来非常丑陋 我想通过向用户显示打开它的通知来强制用户使用 Javascript 否则提示他该网站无法查看 我该怎么做才能实现这一目标 看看这里 无脚本标签 http w
  • Android 设备可以同时在外围模式和中央模式下运行蓝牙 LE 吗?

    是否可以在运行外设和中央模式的 Android 设备中安装 LE 蓝牙 同时用于广告和收听 是的 您绝对可以作为外设并同时连接其他外设 对此的限制之一是设备限制 请下载BLE 中央 外设检查器请确保您的设备支持 BLE 外设 BLE 中央或
  • WinAPI:如何在自定义编辑控件中处理键盘输入

    因此 我使用 Windows API 在 C 中创建自己的编辑控件 多行文本框 一切进展顺利 但我对一件事有点困惑 首先 该控件被构建为能够处理 unicode 并且所有输入都将转换为 unicode 换句话说 所有输入都将存储为wchar
  • 如何在JavaEE中响应后执行代码

    我尝试找到一种在响应后运行代码的方法 但没有成功 就我而言 服务器向我发送数据以便让我完成工作 但此操作可能会很长 例如 向 5000 个联系人发送短信并检查谁收到了它 服务器期望立即收到 HTTP 204 No Content 响应 以确
  • 在 if/else 中使用 Promise

    我有一个条件语句 其中我需要执行两个操作之一 然后在任一操作解决后继续 所以我的代码目前如下所示 if shoud do thing a should do thing a is just a variable that determine
  • 从 Arraylist 中获取恰好出现 3 次的字符串

    我有一个ArrayList其中包含一些重复的值和出现三次的元素 我想将那些出现三次的值专门收集到另一个中ArrayList like Arraylist
  • 如何通过递减来拉伸 numpy 数组的特定项?

    给定边界值k 有没有一种矢量化的方式来替换每个数字n连续递减的数字从n 1 to k 例如 如果k是 0 我想更换np array 3 4 2 2 1 3 1 with np array 2 1 0 3 2 1 0 1 0 1 0 0 2
  • WTForms 不验证 - 没有错误

    我在使用 WTForms 库时遇到了一个奇怪的问题 为了进行测试 我创建了一个包含单个字段的表单 class ArticleForm Form content TextField Content 它接收一个简单的字符串作为内容 现在我使用f
  • 如何找出应用程序崩溃的原因 - Windows 10 LTSB

    我有使用 VS 2017 15 7 4 构建的应用程序 它是 64 位命令行 C 应用程序 我已将其与所有依赖项 DLL 一起复制到使用 Windows 10 Enterprise 2016 LTSB 64 位 版本为版本 10 0 143
  • @Published 属性包装器不适用于 ObservableObject 的子类

    我有一个符合 ObservableObject 协议的类 并使用它自己的变量和 Published 属性包装器创建了一个子类来管理状态 使用子类时 published 属性包装器似乎被忽略 有谁知道这是否是预期行为以及是否有解决方法 我正在
  • 确保列表中的所有字典都具有相同的键

    我有一个包含字典的列表 例如 x 42 x 23 y 5 并希望确保所有字典具有相同的键 其值为None如果原始字典中不存在该密钥 所以上面的列表应该变成 x 42 y None x 23 y 5 最美丽 最Python式的方法是什么 目前
  • flutter firebase querysnapshot:dart 代码中不区分大小写的方法

    我是连接了 firebase 的 flutter 用户 当用户调用搜索功能然后提交字符串时 我尝试使用 querysnapshot 调用云 Firestore 中的用户列表 我尝试过的代码片段如下 Future
  • Android 触摸时旋转图像

    我正在编写一段代码 它使用 onTouchListener 缩放图像 缩放图像并移动 现在我想使用触摸旋转图像 以下是我的代码 Override public boolean onTouch View v MotionEvent rawEv
  • 没有路线匹配 {:action=>"show", :controller=>"schools"} 缺少必需的键:[:id]

    我不知道为什么我无法为项目中的每所学校创建信息链接 这是完整的错误 缺少与 action gt show controller gt schools 匹配的路线 必需的键 id 这是我的index html erb br school co
  • 是否可以从 Google Play 下载我的应用程序的旧 APK?

    在过去的几个月里 我发布了我的应用程序的几个修订版 不幸的是 我没有保留所有旧APK的副本 现在我想测试从旧版本升级到新版本 有什么方法可以下载我的旧版本的 Google 副本吗 Google Play 开发者控制台显示了我的旧 APK 但
  • 如何解决 ASP.NET、VB.NET 中的会话问题?

    如何解决 ASP NET VB NET 中的会话问题 有以下要求 当授权用户登录系统时 不允许该用户从其他计算机或除该用户当前使用权以外的浏览器登录 我们采用的补救措施是 我们将 Is Loggedin 作为数据类型为 bit 的列保留在
  • 在 Android Studio 中或在您的系统上找不到已安装的 Gradle 版本来安装 gradle 包装器

    我在安装最新的 android studio 3 5 1 后安装了 android studio 3 5 1 同时尝试运行我的 CORDOVA android 应用程序 出现以下错误 Checking Java JDK and Androi
  • 流音频运行 underlock

    我正在尝试使用在锁定屏幕下播放流音频PhoneApplicationService Current ApplicationIdleDetectionMode IdleDetectionMode Disabled 使用简单的 mp3 文件一切
  • Android的RelativeLayout和wrap_content的高度?

    我正在尝试选择 ListActivity 类似于用于向启动器屏幕添加快捷方式的选择 我已经滚动了自己的页眉和页脚 我希望在屏幕上时将其 粘在 视图的顶部和底部 为了做到这一点 我使用了RelativeLayout 将标题设置为停靠在顶部 将
  • 如何创建隐藏多层向量并将其公开为单个范围的 Boost.Range?

    我有一个无法修改的遗留类层次结构 由于外部库的要求 我需要为 Line 和 Ring 定义 Boost Range 其中两者仅在单次运行中公开点 即 对于 Line 和 Ring 它应该是点的 Boost Range 伪代码来说明 Line