多态成员变量指针的 std::map

2024-01-04

我正在努力实现与字符串键关联的成员变量指针的映射。 所有变量的范围都来自基类“BaseA” 当从映射中访问变量时,只需要使用基类方法(示例中的 getDesc() ),因此不需要检索原始类型。

该代码在GNU g ++ 6.2.1下编译并运行,但根据我读到的内容,reinterpret_cast的使用不可移植,并且可能无法与其他编译器一起使用。 它是否正确?或者这段代码符合C++标准吗? 有没有其他方法可以在不使用reinterpret_cast的情况下做到这一点? 一项要求是“Vars”必须可以使用默认的复制构造函数和复制赋值实现进行复制。

示例代码:

#include <iostream>
#include <sstream>
#include <map>
#include <typeinfo>

using namespace std;

struct BaseA
{
    virtual string getDesc()  = 0;
};

struct A1 : BaseA
{
    string getDesc() override { return "This is A1"; }
};

struct A2 : BaseA
{
    string getDesc() override { return "This is A2"; }
};

struct Vars
{
    A1 a1;
    A2 a2;

    map< string, BaseA Vars::* > vars;

    Vars()
    {
        vars["A1_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a1);
        vars["A2_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a2);
    }

    BaseA& get( const string& key )
    {
        auto it = vars.find( key );
        if ( it != vars.end())
        {
            return this->*(it->second);
        }
        throw std::out_of_range( "Invalid variable key:[" + key + "]");
    }
};                                

int main()
{
    Vars v;

    cout << "a1 description :" << v.get("A1_KEY").getDesc() << endl;
    cout << "a2 description :" << v.get("A2_KEY").getDesc() << endl;

    return 0;
}

是的,有很少有保证 http://en.cppreference.com/w/cpp/language/reinterpret_cast关于什么reinterpret_cast会做,并且从一个指针到成员的转换到另一个不是其中之一(除非您然后转换回原始类型,这并不能真正帮助您)。

执行此操作的安全且简单的方法是使用std::function:

struct Vars
{
    A1 a1;
    A2 a2;

    map< string, std::function<BaseA&(Vars&)> > vars;

    Vars()
    {
        vars["A1_KEY"] = &Vars::a1;
        vars["A2_KEY"] = &Vars::a2;
    }

    BaseA& get( const string& key )
    {
        auto it = vars.find( key );
        if ( it != vars.end())
        {
            return it->second(*this);
        }
        throw std::out_of_range( "Invalid variable key:[" + key + "]");
    }
};

请注意,如果您从不需要vars字典要改变,你可以把它变成static const成员。 (这意味着您需要在源文件中的类外部定义和初始化它。)

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

多态成员变量指针的 std::map 的相关文章

  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 我如何在 C# .NET(win7 手机)中使用“DataContractJsonSerializer”读入“嵌套”Json 文件?

    我有一个问题 如果我的 json 文件看起来像这样 Numbers 45387 Words 空间桶 我可以很好地阅读它 但是如果它看起来像这样 Main Numbers 45387 Words 空间桶 某事 数字 12345 单词 克兰斯基
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 如何在 SqlDataReader.Read() 期间从死锁异常中恢复

    我的 NET 应用程序的事件日志显示 它在从 Sql Server 读取数据时偶尔会出现死锁 这种情况通常非常罕见 因为我们已经优化了查询以避免死锁 但有时仍然会发生 过去 我们在调用ExecuteReader函数在我们的SqlComman
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • Python 3在for循环中更改字典键的值不起作用

    我的 python 3 代码没有按预期工作 def addFunc x y print x y def subABC x y z print x y z def doublePower base exp print 2 base exp d
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐

  • 使用 Terraform 部署到多个 AWS 账户?

    我一直在寻找一种能够在 Terraform 中同时部署到多个 AWS 帐户的方法 但最终还是失败了 AWS 有使用 Stacks 执行此操作的概念 但我不确定是否有办法在 Terraform 中执行此操作 如果是这样 有哪些解决方案 您可以
  • 如何在 Heroku 上使用 Proximo 修复 java.net.BindException?

    我已经在 Heroku 上安装了 Proximo 附加组件 当将该命令添加到现有命令之前时 我从 Java 中收到 BindException 这是我的前置命令的样子 web bin proximo sh target bin webapp
  • 客户端代码的 Laravel Mix / Webpack 环境依赖变量

    我正在寻找一种在我的开发机器上使用 Laravel Mix 构建我的资产的方法 然后该方法将与生产中的参数相匹配 例如 我的 API 有一个基本 url 它是http foo test api v1为当地发展和https foo com a
  • 使用 Qt 以编程方式确定多桌面环境中的屏幕几何形状

    我正在使用 Qt 4 8 编写一个屏幕截图应用程序 有点像 puush 并且我在多个屏幕设置方面遇到了麻烦 尤其是当主显示器 坐标 0 0 不是最左边的 警告 这不是这个问题的重复 使用Qt4捕获多个屏幕桌面图像 https stackov
  • 尝试包含加密模块时出错:无法解析“加密”

    我正在 React JS 中进行注册用户设置 安装了加密库以保护密码 但是当我运行该程序时 它给了我一个错误 node modules jwa index js 中的错误 5 13 30 找不到模块 错误 无法解析 E Node 中的 加密
  • 如何使用 Google App Engine Blobstore 压缩图像

    我们有一个应用程序 用于处理来自 blobstore 的一系列图像 一个 例子在这里 http lh4 ggpht com f76xUkRZLRkb Qz5uu82TX3LoBRh4eYb9hxYwMRMLCk5ghO OL0DW2v4rR
  • vCPU 是否可以使用两台不同硬件计算机的不同 CPU

    我搜索过这个问题 但似乎没有得到公平的答案 假设我不想创建一个具有 vCPU 的虚拟机 并且该 vCPU 必须有 10 个核心 但我只有 2 台计算机 每台计算机有 5 个物理 CPU 核心 是否可以通过依赖这两个物理 CPU 来创建一个
  • USB 3.0 密钥上的大型 SVN 存储库 - 如何加速和简化?

    关于如何将版本控制存储库检出到 USB 密钥的最佳实践 存在一些现有问题 但这些问题都是在 USB 3 0 出现之前出现的 由于技术 USB 规范和成本相关的原因 USB 2 0 拇指驱动器对于小文件的性能令人惊讶地低迷 由于我们使用集中式
  • PostgreSQL:查找到目前为止的连续天数

    给定一堆带有时间戳字段的记录 代表我的应用程序中的签到 确定当前连续签到的好方法是什么 换句话说 按照签到时间降序排序 直到用户错过一天为止 总共有多少条记录 目前我正在使用这种技术 SELECT distinct uca created
  • 能被 n 整除的数的算法

    首先用户给出一个数字 n 来编程 例如5 程序必须找到可以整除的最小数n 5 并且该数字只能由数字 0 和 9 组成 不能包含任何其他数字 例如 如果用户给出5来编程 能被5整除的数有 5 10 15 20 25 30 85 90 95 但
  • 如何在 VB.NET 中使用 MSHTML?

    在问题 的回答中56107 https stackoverflow com questions 56107 what is the best way to parse html in c Erlend 提供了这个示例 C 代码 using
  • 在 Spark 2.2 之前,表统计数据还有用吗?

    Spark 2 2引入了基于成本的优化 CBO https databricks com blog 2017 08 31 cost based optimizer in apache spark 2 2 html https databri
  • 如何帮助 gcc 向量化 C 代码

    我有以下 C 代码 第一部分只是将复数矩阵从标准读入矩阵中 称为M 有趣的部分是第二部分 include
  • 如何在eclipse中比较两种方法

    我想比较两个我认为相同的方法 但是 Eclipse 重构不会从它们的内容中提取方法 我可以使用 eclipse Compare 比较它们两个吗 这些方法属于同一类 我使用的是 Eclipse Kepler 因此根据您的版本 您的情况可能会有
  • XML XSD 命名空间问题

    我正在尝试使用银行帐户示例定义一个简单的 XML 和 XSD 文件 这是定义 XML 文件的 XSD
  • runOnUIThread 问题

    我正在使用列表视图创建一个下载管理器 它将通过进度条显示当前下载的内容 我可以知道如何更新进度条吗 例如 我有3节课 main class 是一个列表视图 mAdapter class 扩展了 ArrayAdapter mThread cl
  • 移动目标元素时不会触发单击处理程序

    考虑以下演示https stackblitz com edit angular pur1dt https stackblitz com edit angular pur1dt 我有反应式表单控件 带有同步验证器 当字段无效时 错误消息显示在
  • “pagerror.gif”的意义?

    我的网站上有一个名为 pagerror gif 的不存在文件受到奇怪的点击 从一些基本的谷歌搜索来看 它似乎是 Internet Explorer 在某些情况下查找的文件 任何人都可以验证这一点 也许还可以提供一些有关 IE 何时查找该文件
  • 分页编译问题:不确定如何将游标转换为该方法的返回类型

    我一直在尝试在 Android 架构组件中使用 google 提供的 Room 来实现分页库 但是它在我的中显示编译时错误UserDao Class 这是错误 Error 22 42 error Not sure how to conver
  • 多态成员变量指针的 std::map

    我正在努力实现与字符串键关联的成员变量指针的映射 所有变量的范围都来自基类 BaseA 当从映射中访问变量时 只需要使用基类方法 示例中的 getDesc 因此不需要检索原始类型 该代码在GNU g 6 2 1下编译并运行 但根据我读到的内