每个奇特的指针都应该是迭代器吗?

2023-12-15

我正在为 C++ 开发基于段的内存分配器。在这个分配器中,当你释放一块内存时,你必须知道是哪块内存segment它来自。因此,我将指向该段的指针存储为花哨的成员pointer从分配器返回allocate功能。

只是为了显示我正在谈论的界面:这是fancy_memory_resource支持我的分配器...

template<class Ptr>
class fancy_memory_resource {
public:
    Ptr allocate(size_t bytes, size_t align = alignof(max_align_t)) {
        return do_allocate(bytes, align);
    }
    void deallocate(Ptr p, size_t bytes, size_t align = alignof(max_align_t)) {
        return do_deallocate(p, bytes, align);
    }
    bool is_equal(const fancy_memory_resource& rhs) const noexcept {
        return do_is_equal(rhs);
    }
    virtual ~fancy_memory_resource() = default;
private:
    virtual Ptr do_allocate(size_t bytes, size_t align) = 0;
    virtual void do_deallocate(Ptr p, size_t bytes, size_t align) = 0;
    virtual bool do_is_equal(const fancy_memory_resource& rhs) const noexcept = 0;
};

(请注意std::pmr::memory_resource可以作为 typedef 实现fancy_memory_resource<void*>。这是我故意的。)

与此同时,Ptr有问题的是一个名为的奇特指针类型segmented_fancy_pointer<T>(未图示)继承自 CRTP 类型fancy_ptr_base<T, segmented_fancy_pointer<T>>...

template<class T, class CRTP>
struct fancy_ptr_base {
    constexpr T *ptr() const noexcept { return m_ptr; }
    constexpr explicit operator T*() const noexcept { return ptr(); }
    constexpr explicit operator bool() const noexcept { return ptr() != nullptr; }
    constexpr bool operator==(CRTP b) const { return ptr() == b.ptr(); }
    constexpr bool operator!=(CRTP b) const { return ptr() != b.ptr(); }
    constexpr bool operator==(decltype(nullptr)) const { return ptr() == nullptr; }
    constexpr bool operator!=(decltype(nullptr)) const { return ptr() != nullptr; }
    constexpr bool operator<(CRTP b) const { return ptr() < b.ptr(); }
    constexpr bool operator<=(CRTP b) const { return ptr() <= b.ptr(); }
    constexpr bool operator>(CRTP b) const { return ptr() > b.ptr(); }
    constexpr bool operator>=(CRTP b) const { return ptr() >= b.ptr(); }
    constexpr T& operator*() const noexcept { return *ptr(); }
    constexpr T* operator->() const noexcept { return ptr(); }
    constexpr CRTP& operator+=(ptrdiff_t i) { m_ptr += i; return as_crtp(); }
    constexpr CRTP& operator-=(ptrdiff_t i) { m_ptr -= i; return as_crtp(); }
    constexpr CRTP& operator++() { ++m_ptr; return as_crtp(); }
    constexpr CRTP& operator--() { --m_ptr; return as_crtp(); }
    constexpr CRTP operator++(int) { auto r(as_crtp()); ++*this; return r; }
    constexpr CRTP operator--(int) { auto r(as_crtp()); --*this; return r; }
    constexpr CRTP operator+(ptrdiff_t i) const { auto r(as_crtp()); r += i; return r; }
    constexpr CRTP operator-(ptrdiff_t i) const { auto r(as_crtp()); r -= i; return r; }
    constexpr ptrdiff_t operator-(CRTP b) const { return ptr() - b.ptr(); }

protected:
    T *m_ptr = nullptr;
private:
    constexpr CRTP& as_crtp() { return *static_cast<CRTP*>(this); }
    constexpr const CRTP& as_crtp() const { return *static_cast<const CRTP*>(this); }
};

template<class CRTP>
struct fancy_ptr_base<void, CRTP> {
    constexpr void *ptr() const noexcept { return m_ptr; }
    constexpr explicit operator void*() const noexcept { return ptr(); }
    constexpr explicit operator bool() const noexcept { return ptr() != nullptr; }
    constexpr bool operator==(CRTP b) const { return ptr() == b.ptr(); }
    constexpr bool operator!=(CRTP b) const { return ptr() != b.ptr(); }
    constexpr bool operator==(decltype(nullptr)) const { return ptr() == nullptr; }
    constexpr bool operator!=(decltype(nullptr)) const { return ptr() != nullptr; }
    constexpr bool operator<(CRTP b) const { return ptr() < b.ptr(); }
    constexpr bool operator<=(CRTP b) const { return ptr() <= b.ptr(); }
    constexpr bool operator>(CRTP b) const { return ptr() > b.ptr(); }
    constexpr bool operator>=(CRTP b) const { return ptr() >= b.ptr(); }
protected:
    void *m_ptr = nullptr;
};

现在来说说真正的问题。当我去使用我的segmented_allocator<T>(未图示)与 libc++ 的std::vector,一切正常。当我尝试将它与 libstdc++ 一起使用时std::vector, 它失败:

In file included from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_algobase.h:67:0,
                 from /opt/wandbox/gcc-head/include/c++/8.0.0/vector:60,
                 from prog.cc:1984:
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_iterator.h: In instantiation of 'class __gnu_cxx::__normal_iterator<scratch::segmented_fancy_pointer<int>, std::vector<int, scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> > > >':
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/vector.tcc:105:25:   required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int}; _Tp = int; _Alloc = scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> >; std::vector<_Tp, _Alloc>::reference = int&]'
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_vector.h:954:21:   required from 'void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = scratch::pmr::propagating_polymorphic_allocator<int, scratch::segmented_fancy_pointer<int> >; std::vector<_Tp, _Alloc>::value_type = int]'
prog.cc:1990:18:   required from here
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_iterator.h:770:57: error: no type named 'iterator_category' in 'struct std::iterator_traits<scratch::segmented_fancy_pointer<int> >'
       typedef typename __traits_type::iterator_category iterator_category;
                                                         ^~~~~~~~~~~~~~~~~

Now, I can通过添加“迭代器特征”typedef 来解决这个问题fancy_ptr_base<T, CRTP>, 像这样:

    using pointer = CRTP;
    using reference = T&;
    using value_type = std::remove_cv_t<T>;
    using iterator_category = std::random_access_iterator_tag;
    using difference_type = ptrdiff_t;

但我必须这样做吗?是吗required每个奇特的指针类型也是迭代器类型吗?或者 libc++ 做正确的事而 libstdc++ 做正确的事vector只是有一个错误?

(我已经说服自己了most 迭代器不是花哨的指针。这个问题是由我突然怀疑也许所有花哨的指针确实是迭代器。)


是的,您需要满足以下要求:随机访问迭代器。 C++ 标准 [分配器.要求]/5:

分配器类型X将....X::pointer and X::const_pointer还应满足随机访问迭代器的要求。

因此,特别是,您的奇特指针类型需要每个指针类型所需的五个成员类型iterator.

你似乎也失踪了fancy_memory_resource<Ptr>::value_type,一些需要的非成员函数,以及一些noexcept关键词。请查看分配器类型的要求并仔细键入它们的指针。

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

每个奇特的指针都应该是迭代器吗? 的相关文章

  • boost::asio + std::future - 关闭套接字后访问冲突

    我正在编写一个简单的 TCP 客户端来发送和接收单行文本 异步操作由 std future 处理 以便于超时阻塞查询 不幸的是 我的测试应用程序在破坏服务器对象时因访问冲突而崩溃 这是我的代码 TCP客户端 hpp ifndef TCPCL
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 将内置类型转换为向量

    我的 TcpClient 类接受vector
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 如何在 C# 中调整图像大小同时保持高质量?

    我从这里找到了一篇关于图像处理的文章 http www switchonthecode com tutorials csharp tutorial image editing saving cropping and resizing htt
  • 如何使用 Word Automation 获取页面范围

    如何使用办公自动化找到 Microsoft Word 中第 n 页的范围 似乎没有 getPageRange n 函数 并且不清楚它们是如何划分的 这就是您从 VBA 执行此操作的方法 转换为 Matlab COM 调用应该相当简单 Pub
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 如何通过Socket发送字符串数组对象?

    我有字符串数组对象 可以说 String names new String 7 我还通过在客户端系统上使用 ObjectOutputStream 将其存储到文件中来使该对象持久化 我正在使用 ObjectInputStream 读取存储的对
  • 使用 JavaScript 进行表单验证

    我正在尝试使用 JavaScript 验证表单 但我有点坚持在字段旁边显示一条消息说 此字段是必需的 我该怎么做呢 抱歉 我对 JavaScript 很陌生 这是我的js代码 var allFieldsRequired true funct
  • iOS 9 / Xcode 7 上的 SpriteKit 场景屏幕偏移

    我将一个 SpriteKit 项目从 Xcode64 移动到 Xcode7 在 iOS9 模拟器中运行它 屏幕内容发生了变化 在iOS8模拟器中运行时不会移位 iOS9模拟器截图 在Xcode7中缩放SpriteKit场景会以不同的中心缩放
  • 在 JBoss 上使用 Spring MVC Java Config 出现 404 错误

    我使用 Java Config 编写了一个小型 Spring MVC 应用程序 它在 Tomcat 上工作得很好 但在 JBoss EAP 6 2 上却不行 它已成功部署在 JBoss 上 但当我请求 Spring MVC 定义的任何页面和
  • Durandal 2.0 自定义对话框

    我希望制作一个 Durandal 自定义对话框 在现有的可组合视图模型周围添加一个带有标题和页脚的窗口框架 我制作了一个 customModal html 模板 div class messageBox div class modal he
  • Wordpress AJAX 不起作用 - 响应 0

    我想为我的插件添加 AJAX 支持 但我对这个简单的事情有很大的问题 WordPress 不允许我使用普通 AJAX 我需要使用 WordPress 版本 在任何时候 WordPress 函数 应该生成输出 都会返回 0 我认为原因是 WP
  • 为什么我会收到SettingWithCopyWarning a value is试图在切片副本上设置的警告? [复制]

    这个问题在这里已经有答案了 运行以下代码时 import pandas as pd df pd DataFrame A 1 2 3 B 2 4 8 df2 df df A lt 3 df2 C 100 我收到以下警告 SettingsWit
  • 在内存有限的情况下,如何优雅地降低性能?

    过去几天我一直在尝试消除游戏中的内存泄漏 从而导致许多内存不足错误 我即将添加大量图形 虽然不是非常复杂 但会显着增加系统的处理要求 而且我有点担心我的内存使用情况 我希望有人可能有给我一些建议 我不想低于 Android 2 1 所以请为
  • 如何动态更改Viewpager选项卡颜色?

    如何像这样改变标签的颜色 当我单击 滑动到绿色或任何其他选项卡时 选项卡颜色应更改为适当的颜色 其余其他选项卡颜色应更改为黑色 我怎样才能做到这一点 我正在使用 Viewpager 我在 onpagelistener 中尝试了这段代码 if
  • Java - .Net 对象交换,不基于 Web

    我有一个用 C 实现的客户端 服务器系统 客户端和服务器通过序列化 反序列化交换 Net 对象并通过 TCP IP 进行通信 它在本地网络上运行 不是基于 Web 或基于 Internet 现在我想包括通过 wifi 连接的 Android
  • 如何将透视变换应用于 UIView?

    我正在寻找对 UIView 执行透视变换 例如在 coverflow 中看到的 有谁知道这是否可能 我调查过使用CALayer并浏览了所有务实程序员的核心动画播客 但我仍然不清楚如何在 iPhone 上创建这种转换 任何帮助 指示或示例代码
  • 未捕获的错误:未找到“App\Kernel”类

    当我想运行任何 php bin console 命令时 我目前面临一个重要问题 Symfony Component ErrorHandler Error ClassNotFoundError 29 message Attempted to
  • 使大型处理工作变得更小

    这是我在寻找解决方案时使用的代码 public function indexAction id3 options options array version gt 3 0 encoding gt Zend Media Id3 Encodin
  • 我可以确定当前的测试执行人员是来自测试实验室还是来自 QTP IDE 中的交互式测试?

    检查当前 QTP 测试执行是否是交互式的 即不是从 QC 测试实验室启动的 QC 测试集执行的一部分 的最有效方法是什么 你们知道一个很酷的方法吗 WR 曾经有一个批处理运行标志 对于 IDE 内的所有执行 该标志都会被可靠地清除 也许QT
  • Bootstrap 4 - 粘性页脚 - 动态页脚高度

    我需要在我的页面上放置一个粘性页脚 但是我没有为页脚设置明确的高度 在较小的屏幕上 行的大小会调整 页脚会变长 因此 getbootstrap 上提供的默认粘性页脚示例不起作用 因为它需要固定的页脚高度 有什么方法可以实现这个吗 Stick
  • 使用 Apache poi 从 docx 获取文本样式

    我正在尝试从 MS docx 文件中获取样式信息 使用添加的样式 如粗体 斜体 编写文件内容没有问题 字体大小等 但读取文件内容并获取样式信息不太清楚 我尝试过使用 XWPFDocument 这个 API 似乎没有读取样式的能力 我现在正在
  • 如何在使用 swift 继续访问视图控制器之前实例化并加载视图控制器

    当我从 viewController A 转到 viewController B 时 我遇到了一个问题 在继续执行之前大约有 5 秒的延迟 我相信这是由于我在 viewDidLoad 中加载的视图数量所致 我有一个 xib 文件 其中包含代
  • 我可以在电子邮件中嵌入 Twitter 源吗?

    我即将向我的客户发送一封电子邮件活动 电子邮件将以 HTML 格式发送 我想在电子邮件中嵌入 Twitter 提要 类似于您在博客和网站中看到的嵌入 Twitter 小部件 当我复制并粘贴通过 Twitter 网站生成的代码时 我的电子邮件
  • 如何使用单声道解决 OSX 上的 SecureChannelFailure

    我正在尝试访问https geocoder cit api here com在单声道上使用 NET F 我正在使用Http帮手来自FSharp Data使用以下代码 let baseUrl https geocoder cit api he
  • 每个奇特的指针都应该是迭代器吗?

    我正在为 C 开发基于段的内存分配器 在这个分配器中 当你释放一块内存时 你必须知道是哪块内存segment它来自 因此 我将指向该段的指针存储为花哨的成员pointer从分配器返回allocate功能 只是为了显示我正在谈论的界面 这是f