C++ 将函数指针转换为唯一的“哈希”键

2024-03-27

Se 原始问题在底部。

我想我明白你们现在在说什么——因为成员函数指针的内部结构是编译器/机器特定的,所以我实际上不可能做到这一点。因此,即使它在我测试时有效,我也不能保证它在其他编译器/机器上也有效。

那么还有其他方法可以实现我想要的吗?

我有一个模板类和该类的基模板类,并且有一个委托类,其中包含委托类在调用时应调用的所有事件的 std::map。

我需要映射的原因是,既确保相同的成员函数(指向成员函数的事件)不会添加多次,又可以使用最初使用的对象和成员函数从映射中删除事件实例化事件对象。

template <class T_arg1> struct EventBase1
{
public:
    bool operator < (const EventBase1 &event1) const { return _key < event1._key; };
    virtual void operator()(T_arg1 t1) const {};
    std::pair<intptr_t, intptr_t> _key;
};

template <class T, class T_arg1> struct Event1: public EventBase1<T_arg1>
{
    template <class T_arg1> friend class Delegate1;
    typedef typename void (T::*Method)(T_arg1);
private:
    Method _method;
    T* _object;
public:
    Event1(T* object, Method method): _object(object), _method(method)
    {
        _key = std::pair<intptr_t, intptr_t>(reinterpret_cast<intptr_t>(object), reinterpret_cast<intptr_t>( reinterpret_cast<void*&>(method)));
    };
    virtual void operator()(T_arg1 t1) const {
        (_object->*_method)(t1);
    };
};

template <class T_arg1> class Delegate1
{
public:
    typedef typename EventBase1<T_arg1> T_event;
    void operator += (T_event* observer)
    {
        assert(observer);
        _observers[*observer] = observer;
    };
    void operator -= (const T_event &observer)
    {
        std::map<T_event, T_event*>::iterator i = _observers.find(observer);
        if(i != _observers.end()) {
            delete i->second;
            _observers.erase(i);
        }
    };
    void operator()(T_arg1 t1)
    {
        for(std::map<T_event, T_event*>::iterator i = _observers.begin(); i != _observers.end(); i++) {
            (*(i->second))(t1);
        }
    };
private:
    std::map<T_event, T_event*> _observers;     
};

原问题:

我将函数指针存储在std::map,我正在为地图生成密钥,如下所示:std::pair<int, int>( (int)((int*)object), (int)(static_cast<const void*>(&method)) ).

method是一个函数(方法)指针,并且object是指向方法对象的指针。

它有效,但我偷偷怀疑我获取密钥第二部分的方式并不完全正确。

我从来没有完全理解函数指针,但我想我得到的是指针的地址而不是函数的地址,编译器不会让我这样做((int)(static_cast<const void*>(method))).

所以我的问题是 - 如何从函数指针获取唯一的密钥,如果我稍后从指向相同方法的另一个函数指针获取密钥,该密钥将是相同的?

提前致谢, 马丁


第二个是不合法的:形式上,你不能将指针转换为 函数指向数据的指针(以及void*是一个指向数据的指针)。 另外,不保证您能够将任何指针转换为int;转换仅在以下情况下才合法int至少和 a 一样大 指针(这意味着您的代码应该无法在大多数 64 位平台上编译) 位系统)。

有几种方法可以解决这个问题。首先,关于大多数(全部?)现代 机器、函数指针和数据指针do有相同的 大小和代表性。 (事实上​​,Posix 需要它。即使它 我使用的第一台 Unix 机器上并非如此。)如果我们假设这一点, 您可以通过使用来保证足够大的整数类型intptr_t, 和 使用额外的间接级别“欺骗”编译器:

std::pair<intptr_t, intptr_t>(
    reinterpret_cast<intptr_t>( reinterpret_cast<void*&>( object ) ),
    reinterpret_cast<intptr_t>( reinterpret_cast<void*&>( method ) ) )

(这假设object and method你的指针是 对象和函数。)

请注意,这确实not适用于指向成员函数的指针。 指向成员函数的指针是完全不同的野兽,我不这么认为 认为有什么有效的方法可以以这种方式使用它们作为密钥 (因为它们可能并且经常包含填充或未设置的字段, 某些情况)。

就此而言,正式而言,即使对于正常情况也不能真正保证这一点 指针。该标准允许指针具有无关位,或者 几个不同的指针表示形式来比较相等。在 然而,在实践中,它在大多数(所有?)现代机器上都是安全的。

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

C++ 将函数指针转换为唯一的“哈希”键 的相关文章

  • 为什么在排序输入上插入到树中比随机输入更快?

    现在我一直听说从随机选择的数据构建二叉搜索树比有序数据更快 这仅仅是因为有序数据需要显式重新平衡以将树高度保持在最低限度 最近我实现了一个不可变的treap http en wikipedia org wiki Treap 一种特殊的二叉搜
  • 如何从对Web服务发出的请求中获取客户端IP地址

    我的 IIS 中托管有一个 Web 服务 当客户端直接使用我的服务时 我需要找出客户端 IP 地址 like http MyIpAddress MyApplication MyWebServiceClass asmx http MyIpAd
  • 为基于架构的 XML 文件创建 WPF 编辑器

    这是场景 我们的服务器产品之一使用大型 XML 配置文件 该文件的布局相当好 并且针对 XSD 文件进行了验证 现在是时候构建一个配置 GUI 来维护这个文件了 我想深入研究 WPF 来完成它 我可以为每个配置部分布置一个单独的表单 每次向
  • C++ 中可以使用匿名类作为返回类型吗?

    有没有办法在 C 中使用匿名类作为返回类型 我用谷歌搜索这可能有效 struct Test fun 但是这段代码无法编译 错误信息是 新类型不能在返回类型中定义 其实代码没有任何意义 我只是想弄清楚匿名类是否可以用作C 中的返回类型 这是我
  • 使用正则表达式解析日志文件

    我目前正在为我们的内部日志文件 由 log4php log4net 和 log4j 生成 开发一个解析器 到目前为止 我有一个很好的正则表达式来解析日志 除了一个烦人的一点 一些日志消息跨越多行 我无法正确匹配 我现在的正则表达式是这样的
  • 如何修复此 YCrCb -> RBG 转换公式?

    我使用的公式来自这个问题 https stackoverflow com questions 8838481 kcvpixelformattype 420ypcbcr8biplanarfullrange frame to uiimage c
  • 我们什么时候应该在.NET中使用NativeMemory.Alloc()? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 NET6 C 引入NativeMemory类 但我不知道什么时候应该使用NativeMemory Alloc 而不是普通的数组实例化
  • WPF ComboBox 中具有本地化名称的枚举

    我有一个列出枚举的组合框 enum StatusEnum Open 1 Closed 2 InProgress 3
  • 是否可以在对Where 的调用中调用命名方法?

    我试图从 RedGate 的这本免费电子书中了解 Linq 的一些性能影响ftp support red gate com ebooks under the hood of net memory management part1 pdf f
  • C# SignalR 异常 - 连接在收到调用结果之前开始重新连接

    我正在开发 2 个应用程序 第一个是 C 控制台应用程序 另一个是 Asp net Web 应用程序 我正在使用 SignalR 连接两者 这是我的 C 控制台应用程序 客户端 public class RoboHub public sta
  • C# 从今天起 30 天

    我需要我的应用程序从今天起 30 天后过期 我会将当前日期存储在应用程序配置中 如何检查应用程序是否已过期 我不介意用户是否将时钟调回来并且应用程序可以正常工作 用户太愚蠢而不会这样做 if appmode Trial string dat
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor
  • C# XML 反序列化。将节点中的所有内部文本读取到字符串属性中

    我目前正在尝试修改我的类 以便我的模型上的文本属性包含某个节点的所有内部文本 text node 给我带来问题的 xml 示例是
  • OpenSSL:无需 SSL_read() / SSL_write() 即可执行加密/解密

    我已经用 C 语言编写了一个基于事件的网络库 现在我想通过 OpenSSL 添加 SSL TLS 支持 而不是使用SSL read and SSL write 我宁愿让 OpenSSL 只执行传出 传入数据的加密 解密 让我自己传输 接收数
  • 为什么在 C++ 类中的数据成员上使用像 m_ 这样的前缀?

    许多 C 代码使用语法约定来标记数据成员 常见的例子包括 m memberName对于公共成员 在所有使用公共成员的情况下 memberName对于私人会员或所有会员 其他人尝试强制使用this gt member每当使用数据成员时 根据我
  • 提升shared_from_this<>()

    有人可以用几句话概括一下如何提升shared from this lt gt 应该使用智能指针 特别是从使用绑定函数在 io service 中注册处理程序的角度来看 编辑 一些回复要求提供更多背景信息 基本上 我正在寻找 陷阱 即人们使用
  • OpenCV 仅围绕大轮廓绘制矩形?

    第一次发帖 希望我以正确的方式放置代码 我正在尝试检测和计算视频中的车辆 因此 如果您查看下面的代码 我会在阈值处理和膨胀后找到图像的轮廓 然后我使用 drawContours 和矩形在检测到的轮廓周围绘制一个框 我试图在 drawCont
  • Cordova 上的 ClearCookiesAsync()

    我正在尝试使用 wp8 cordova 中的插件来清除 WebBrowser cookie 我已经让它与 JavaScript 进行通信 并且我的 c 文件中有类似这样的内容 using WPCordovaClassLib Cordova
  • 从最大到最小的3个整数

    我是 C 初学者 我使用 编程 使用 C 的原理与实践 第二版 问题如下 编写一个程序 提示用户输入三个整数值 然后以逗号分隔的数字顺序输出这些值 如果两个值相同 则应将它们排列在一起 include
  • C#“var”关键字在 VB.NET 中的等价物是什么?

    例如 我如何获得 VB NET静态类型局部变量是static赋值右侧的表达式的类型 像这样 Dim http msdn microsoft com en us library 7ee5a7s1 aspx我的变量 3 你还需要 选项推断 ht

随机推荐

  • 将 JSON 数据存储在 MySQL 表中

    我在使用 NodeJS 在 MySQL 表中存储 JSON 数据时遇到问题 JSON 数据如下所示 header file1 0 file2 1 subfiles subfile1 true subfile2 true response n
  • qVariantValue 是“QT_DEPRECATED” - 替代品是什么?

    我需要将 Qt 遗留代码从 4 转换为 5 1 现在我在 Visual Studio 2010 中出现编译错误 SingleItem item qVariantValue
  • 通过 Javascript WeakMaps 进行垃圾收集缓存

    我想在 JavaScript 中缓存大对象 这些对象是通过键检索的 缓存它们是有意义的 但它们不会一次全部放入内存中 因此我希望在需要时对它们进行垃圾收集 GC 显然更了解 使用以下命令创建这样的缓存非常简单WeakReference or
  • 安全跨线程信号/槽 C++

    似乎唯一为 Signal 类和槽中调用的内容提供安全跨线程信号的实现是 QT 也许我错了 但我不能在我正在做的项目中使用QT 那么我如何从不同的线程提供安全的 Slots 调用 例如使用 Boost signals2 插槽内的互斥体是唯一的
  • React Hooks with typescript:类型上不存在属性“数据”

    我有一个没有意义的错误 我正在用钩子输入我的状态值 但他说错误不是同一类型 已经尝试过使用空数组 甚至使用一些数据的数组 但错误总是相同的 import React useState from react import Row Col fr
  • 仅更新 DateTime 的日期部分

    我正在使用 SQL Server 2008 我在数据库中有一个日期时间 值为 10 4 2012 8 03 00 AM 如何仅更新日期部分 字段名称为 dTime 我想将日期更新为 10 5 2012 并保持时间不变 UPDATE tabl
  • 如果 bean 已经使用 @ConfigurationProperties 注解,@EnableConfigurationProperties 会有什么区别?

    Spring Boot 文档 https docs spring io spring boot docs 2 1 3 RELEASE reference html boot features external config html boo
  • 设置自定义 Maven 2 属性的默认值

    我有一个 Maven pom xml 其中包含一个我希望能够在命令行上控制的插件 一切工作正常 除了即使在网上搜索了一段时间后 我也不知道如何为我的控件属性设置默认值
  • 如何将 Cocoa 坐标从左上角 == 原点转换为左下角 == 原点

    我使用 CGWindowListCopyWindowInfo 来获取所有窗口的列表 它根据原点为我提供每个窗口的坐标top left屏幕的 如果我使用 NSWindow 的 setFrame 方法 则坐标基于原点左下方屏幕的 从一种方式转换
  • WPF 列表框滚动条不起作用

  • Backbone 可以逆序渲染集合吗?

    我正在使用 Signalr 中心来订阅服务器上的事件 事件被分派到集线器 它成功地将项目添加到 Marionette CollectionView 这又被呈现到表格中 因为事件表本质上是一个记事本 所以我希望事件按相反的顺序排列 并且最好只
  • 成本计算器应用程序的设计模式?

    我有一个问题 我之前曾尝试寻求帮助 但当时无法解决它 所以我现在尝试简化问题 看看是否可以获得更具体的帮助 因为它让我发疯了 基本上 我有这个应用程序的工作 更复杂 版本 它是一个项目成本计算器 但因为我同时尝试学习更好地设计我的应用程序
  • iPhone 后台线程问题

    我正在使用后台线程来更新我的标签之一 我正在使用以下代码 但在 iOS 4 0 中 我了解到应用程序会保存其状态并进入后台 我的应用程序也做了这项工作 但是当我隐藏应用程序时 我正在使用的线程停止工作 并在我重新打开它时从我离开的位置恢复
  • IE8 支持哪些 Javascript 版本?

    根据维基百科 IE8仅支持Javascript 1 5 所以他们说 IE8 完全忽略了 Javascript 版本 1 6 1 7 1 8 和 1 9 我应该相信吗 这是真的吗 好吧 实际上 IE 的实现叫做JScript http msd
  • runBlock 发生后延迟 SKAction.sequence 中的下一个操作(Swift)?

    The duration财产为moveTo在 a 内时不被跟随runBlock 允许序列中的后续操作立即执行 而该操作应该只在之后执行duration秒 代码A 正确执行的序列 let realDest CGPointMake itemA
  • Ansible - 如何将 selectattr 与不同键的 yaml 一起使用

    我正在努力尝试做一件简单的事情 我认为这应该很容易 解析 yaml 并过滤 Ansible 中的某些键 我的 yaml 文件如下所示 vm vm1 ip 10 10 10 1 vm vm2 ip 10 10 10 2 test vm som
  • 清空表数据并重置 IDENTITY 列

    我在 SQL Server 中创建了一个包含几个表的数据库 我运行了一些测试 现在准备部署我的解决方案 问题是 表中有各种各样的数据 我想删除通过测试创建的所有表的每一行 并将主键放回到零 我尝试删除它不会重置主键索引 并且删除只是破坏了表
  • 如何使带有换行符的行内元素的背景延伸到每边最远的边缘?

    即使使用容器 我也不知道如何做到这一点 内联容器的背景将缩小到每行的大小 内联块容器将就像块元素一样 浮动似乎也不起作用 Example div style width 250px margin left 0px border 2px so
  • 如果在python中单独写一个变量名会发生什么?

    最近我开始好奇以下伪 python 代码的第 2 行发生了什么 def my fun foo bar foo return foo bar 我开始感兴趣的原因是我正在尝试 Light Table 并尝试在 foo 上放置一个手表 它似乎导致
  • C++ 将函数指针转换为唯一的“哈希”键

    Se 原始问题在底部 我想我明白你们现在在说什么 因为成员函数指针的内部结构是编译器 机器特定的 所以我实际上不可能做到这一点 因此 即使它在我测试时有效 我也不能保证它在其他编译器 机器上也有效 那么还有其他方法可以实现我想要的吗 我有一