如何使用boost预处理器生成访问器?

2024-03-29

例如

class A
{
    int m_x;
    float m_y;
    double m_z;

    int x() const {return m_x;}
    float y() const {return m_y;}
    double z() const {return m_z;}
};

变得像

class A
{
    MY_MACRO((int)(float)(double), (x)(y)(z));
};

请使用 boost 预处理器序列来执行此操作,因为该宏将与已使用 boost 预处理器序列的其他现有宏结合起来。


免责声明:即使您对此答案感到满意,您也应该等待,以防出现更好的答案,因为我远非专家,这些可能不是最好的方法。

第一种方法:

//two different sequences
struct A
{
    MY_MACRO1((int)(float)(double),(x)(y)(z))
};

我认为这种方法给出了看起来不那么可怕的宏:

#define DECLARE_DATA_MEMBER1(R,TYPES,INDEX,NAME) \
BOOST_PP_SEQ_ELEM(INDEX,TYPES) BOOST_PP_CAT(m_,NAME);

#define DEFINE_ACCESSOR1(R,TYPES,INDEX,NAME) \
BOOST_PP_SEQ_ELEM(INDEX,TYPES) NAME(){ return BOOST_PP_CAT(m_,NAME); }

#define MY_MACRO1(TYPES,NAMES) \
BOOST_PP_SEQ_FOR_EACH_I(DECLARE_DATA_MEMBER1,TYPES,NAMES) \
public: \
BOOST_PP_SEQ_FOR_EACH_I(DEFINE_ACCESSOR1,TYPES,NAMES)

MY_MACRO得到两个序列:TYPES and NAMES。为了声明数据成员,我使用BOOST_PP_SEQ_FOR_EACH_I在序列上NAMES使用宏DECLARE_DATA_MEMBER1并具有序列TYPES作为数据。这个“唤起”DECLARE_DATA_MEMBER1有 4 个参数:R这是未使用的(我不知道它是做什么的),TYPES(类型的顺序),INDEX(告诉我们现在处于哪个迭代中,从 0 开始),以及NAME(原元素NAMES与本次迭代相对应的序列)。
的“身体”DECLARE_DATA_MEMBER1 and DEFINE_ACCESSOR1很简单,我们只需得到INDEX类型序列中的第一个元素,并连接m_ with NAME.


第二种方法:

//just one sequence but you need to put two sets of parentheses around each pair
struct B
{
    MY_MACRO2(((int, x))((float,y))((double,z)))
};

这仍然相当简单,但有一个必须使用双括号的不方便之处。

#define DECLARE_DATA_MEMBER2(R,_,TYPE_AND_NAME) \
BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME));

#define DEFINE_ACCESSOR2(R,_,TYPE_AND_NAME) \
BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)(){ return BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)); }

#define MY_MACRO2(TYPES_AND_NAMES) \
BOOST_PP_SEQ_FOR_EACH(DECLARE_DATA_MEMBER2,_,TYPES_AND_NAMES) \
public: \
BOOST_PP_SEQ_FOR_EACH(DEFINE_ACCESSOR2,_,TYPES_AND_NAMES)

这次只有一个序列,因此我们不需要辅助宏中的索引。为此原因BOOST_PP_SEQ_FOR_EACH使用宏用于 TYPES_AND_NAMESDECLARE_DATA_MEMBER2并且不传递任何额外的数据。该宏接收三个“参数”:R再次未使用,_ (or DATA,此处也未使用),以及TYPE_AND_NAME(形式为元组(TYPE,NAME)).
在两个辅助宏的“主体”中BOOST_PP_TUPLE_ELEM用于获取类型(索引=0)或名称(索引=1)。该宏需要传递元组的大小、所需元素的索引和元组。


第三种方法:

//one sequence but the macro is more complex
struct C
{
    MY_MACRO3((int,x)(float,y)(double,z))
};

这个宏大量借鉴了BOOST_FUSION_ADAPT_STRUCT和类似的宏。

//Heavily "inspired" from BOOST_FUSION_ADAPT_STRUCT
#define CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(X, Y)  \
    ((X, Y)) CREATE_MY_MACRO_PLACEHOLDER_FILLER_1
#define CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(X, Y)  \
    ((X, Y)) CREATE_MY_MACRO_PLACEHOLDER_FILLER_0
#define CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END
#define CREATE_MY_MACRO_PLACEHOLDER_FILLER_1_END

#define DECLARE_DATA_MEMBER3(R,_,TYPE_AND_NAME) \
BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME));

#define DEFINE_ACCESSOR3(R,_,TYPE_AND_NAME) \
BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)(){ return BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)); }

#define MY_MACRO3(TYPES_AND_NAMES) \
BOOST_PP_SEQ_FOR_EACH(DECLARE_DATA_MEMBER3,_,BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END)) \
public: \
BOOST_PP_SEQ_FOR_EACH(DEFINE_ACCESSOR3,_,BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END))

在这种方法中,辅助宏基本上没有改变。唯一(大)的区别是 for_each 中使用的序列不仅仅是TYPES_AND_NAMES but BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END)。这是强制使用双括号的巧妙技巧。它的工作原理如下:

CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(int,x)(float,y)_END
    //CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(A,B)->((A,B))CREATE_MY_MACRO_PLACEHOLDER_FILLER_1
((int,x))CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(float,y)_END
    //CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(A,B)->((A,B))CREATE_MY_MACRO_PLACEHOLDER_FILLER_0
((int,x))((float,y))CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END
    //CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END->
((int,x))((float,y))

在 Coliru 上运行。 http://coliru.stacked-crooked.com/a/1ac9bef8c1b6ed87

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

如何使用boost预处理器生成访问器? 的相关文章

  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • 同步执行异步函数

    我对此主题进行了大量搜索 并且阅读了本网站上有关此主题的大部分帖子 但是我仍然感到困惑 我需要一个直接的答案 这是我的情况 我有一个已建立的 Winform 应用程序 但无法使其全部 异步 我现在被迫使用一个全部编写为异步函数的外部库 在我
  • asp.net c# 将数据集中的数据转换为电子邮件正文?

    从数据集到电子邮件正文的最佳方式是什么 我有一个 net 控制台应用程序 用于根据存储过程的结果发送电子邮件通知 并且想知道如何最好地从 SQL 数据转到电子邮件正文 带有颜色和字体的 html 正文是最好的 但纯文本也可以 thanks
  • CMake 和 Visual Studio:如何获得快速、安静的命令行构建?

    我有一个 cmake 项目 它成功地完成了我想要的一切 但我有大约 100 个文件 当我只需要重新编译一个文件时 我厌倦了每次看到生成的巨大输出 每个文件 30 行 明确地说 我正在编译cmake build 得到这个结果 我需要传递给编译
  • 将指针转换为浮点数?

    我有一个unsigned char 通常 这指向一块数据 但在某些情况下 指针就是数据 即 铸造一个int的价值unsigned char 指针 unsigned char intData unsigned char myInteger 反
  • 在桌面应用程序中,类库的连接字符串存储在哪里?我可以在app.config中使用吗?

    我是桌面应用程序开发的新手 目前正在使用分层架构 用户界面 DAL BLL 构建桌面应用程序 在 Web 开发中 我曾经将连接字符串存储在 web config 中 我的类库从那里访问它 请指导我在桌面应用程序中如何以及在何处存储 DAL
  • 如何从 List 中的字符串中删除数字/数字?

    我有一个字符串列表 List
  • 'goto *foo' 其中 foo 不是指针。这是什么?

    我正在玩标签作为值 https gcc gnu org onlinedocs gcc Labels as Values html并最终得到这段代码 int foo 0 goto foo 我的 C C 经验告诉我 foo means dere
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • 以标准用户身份打开默认浏览器 (C++)

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 当 ShellExecute 打开浏览器时 它似乎读取 本地管理员 配置文件而不是用户
  • 获取给定EntityType的导航属性

    我在用VS2010 EF4 0 需要如下功能 private string GetNaviProps Type entityType eg typeof Employee NorthwindEntities en new Northwind
  • 在 ncurses 中使用退格键

    我设置了一个简单的 ncurses 程序 它使用 getch 一次读取一个字符并将它们复制到缓冲区中 我遇到的问题是检测到按下退格键 这是相关代码 while buffer i c getch EOF i if c n break else
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • 无法将方法组“Read”转换为非委托类型“bool”

    我正在尝试使用SqlDataReader检查条目是否存在 如果存在则返回ID 否则返回false 当我尝试编译时 出现错误 无法将方法组 Read 转换为非委托类型 bool 我一直在遵循在 VB 中找到的示例 但似乎翻译可能不正确 pri
  • System.diagnostics.process 进程在托管后无法在 IIS 上运行?

    我正在尝试从网络应用程序安装 exe 当我在本地运行应用程序 从 asp 开发服务器 时 它安装正确 但当我托管在 IIS 上时 它不起作用 我在asp net页面的Page load方法上编写了这段代码 想要在客户端计算机上安装Test
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 如何将 Metro 应用部署到桌面?

    我正在尝试将我的 C 应用程序部署到我的 Windows 8 Metro 桌面 我可以在 bin 文件夹中看到部署的文件 但是当我尝试打开它们时 出现以下错误 该应用程序只能在 AppContainer 的上下文中运行 我检查了属性上下文菜
  • 在代码中而不是 XAML 中呈现 UserControl

    我想用RenderTargetBitmap将 UserControl 呈现为位图 而无需为其编写 XAML 当我这样做时 我得到一张空白图像 我是否错过了关键的一步 ValTool Controls VideoFisheyeOverlayC
  • 具有多种类型的 C# 泛型类型推断

    我有以下通用方法 用于将一种类型的输入对象序列化为超类型 如下所示 public string SerialiseAs
  • 什么时候使用静态库需要头文件?

    如果我在 Linux 中用 C 创建一个静态库并生成 a 文件 我 或其他人 如何使用该库 例如 我的库定义了一个类 我认为仅仅提供 a 文件是不够的 还需要提供头文件 我如何知道 a 文件必须提供哪些头文件 例如 我是否需要提供我的库代码

随机推荐

  • 从 C# 中的文本文件中读取数字

    这应该是很简单的事情 我只想从由空格分隔的标记组成的文本文件中读取数字和单词 在 C 中如何做到这一点 例如 在 C 中 以下代码可以读取整数 浮点数和字 我不想使用正则表达式或编写任何特殊的解析代码 ifstream in file tx
  • 使用 PdfMerger iText7 将 PdfDocument 转换为 byte[]

    我有一个要求 我使用生成不同的 pdf iText 7 1 11 我在用PdfMerger即时合并所有 pdf 我能够在本地系统成功生成 pdf 但应用程序需要发送bye 作为回应 我找到的解决方案here https kb itextpd
  • 标识符前面的::(双冒号)是什么意思?

    这条线 https github com rust lang libc blob 4af234205f440be38d9036a5bdbcfeed55fb2ced src unix linux like mod rs L2来自铁锈libc
  • ASP.NET真正的异步操作

    我正在尝试从 ASP NET 页面发出多个 HTTP 请求 页面本身不需要知道响应 并且应该继续处理并交付页面 我尝试将 HTTP 代码放入 BackgroundWorker 中并异步运行它 但是我最初收到以下错误 在此上下文中不允许异步操
  • 返回上一屏幕时,反应导航焦点立即模糊于输入

    当我导航到新屏幕时 我想专注于文本输入 当我将屏幕添加到堆栈时 这有效 但当我返回堆栈时 这不起作用 相反 输入聚焦一秒钟并立即模糊 这是我得到的 屏幕 A 位于堆栈中的第一个 输入立即模糊 屏幕 B 已添加到堆栈中并按预期工作 知道是什么
  • 尝试上传到使用多个元数据生成的 GCP 签名网址时收到 403

    我生成了一个 GCP 签名网址 标头中包含两个元数据值 例子 x goog meta reviewer 简 x goog meta author 杰克 当我尝试将文件上传到生成的签名 URL 并在标头中设置元数据时 我收到 403 禁止请求
  • SDL_RENDERER_PRESENTVSYNC 显示不一致

    我最近决定开始使用 SDL 作为我的库之一来编写 C 游戏 在编写程序和学习 SDL 的过程中 我偶然发现了程序中的一个特殊错误 并决定在 SSCCE 中复制它 以确保我没有发疯 问题似乎是 当我将 SDL RENDERER PRESENT
  • Powershell v4 不自动导入模块

    我在用Microsoft PowerShell v4 PS C gt get host Name ConsoleHost Version 4 0 InstanceId 3b4b6b8d 70ec 46dd 942a bfecf5fb6f31
  • Facebook 应用程序托管在 Google App Engine 上

    我是 Facebook 应用程序的新手 我已经在 GAE 上启动并运行了一个应用程序 使用 python 我想将它与 Facebook 集成 这样我就可以访问一些用户的数据来帮助我个性化应用程序 例如喜欢的页面 兴趣 他们来自哪里等数据 还
  • 在 GitHub for Windows 中克隆多个分支

    有时我需要在本地磁盘上同时拥有 GitHub 存储库的两个不同分支 尤其是在处理 gh pages 时 我通常通过在不同的文件夹中创建存储库的多个克隆来实现此目的 并使用不同的分支进行克隆 是否可以在 Windows UI 的 GitHub
  • System.Xml.XmlException:给定编码中的字符无效。 8271 行,位置 163

    我正在编写一个简单的 XML 解析器 它将传递以下 XML 输出 http www cpalead com dashboard reports campaign rss php id 187000 http www cpalead com
  • 是否可以使用字典理解来反转Python中的字典

    我想反转字典key value使用字典理解进行配对 但如果新字典的键有多个值 则它将被最后一个值替换 如果重复某个键 是否可以使用理解附加到新字典中的值 Input test di a 1 b 2 c 3 d 2 Code v k for
  • Google Chrome 开发者工具未在 css 旁边显示 css 文件名

    It s a bug of google chrome or there are some guidelines which i should stick to to return that feature 谢谢 UPDATED问题是由 p
  • 如何在 Visual Studio 2008 中保持文档选项卡按上次使用情况排序

    注册表更改是什么 告诉 Visual Studio 始终将当前文档放置在窗口的左侧 默认实现是这样的 如果您打开了 10 个文档 并且您正在编辑第 5 个文档 那么它的选项卡将是该组中的第 5 个选项卡 随着注册表的更改 当您单击第五个文档
  • numpy.array 的总和部分

    假设我有以下数组 a np array 1 2 3 4 5 6 7 8 9 10 11 12 3 5 6 7 8 9 我想对第一行的前两个值求和 1 2 3 然后是接下来的两个值 3 4 7 进而5 6 11 对每一行依此类推 我想要的输出
  • HTML5 章节与文章

    我有一个由各种 部分 组成的页面 例如视频 新闻源等 我有点困惑如何用 HTML5 表示这些 目前我将它们作为 HTML5 section s 但经过进一步检查 看起来更正确的标签是 section
  • 如何从列表创建分组条形图

    我正在尝试绘制一个条形图 它比较两种不同情况下的多个项目的数量 所需的输出将是一个条形图 其中 4 4 8 个条形图彼此相邻 指示每种情况的每种类型的数量 这是我编写的初始代码 它没有给出我的期望 我该如何修改这个 import numpy
  • 如何在 Spring Data Elasticsearch 2.2.3.RELEASE 中配置 Rest 高级客户端的套接字超时

    我将 Spring Boot Starter Data Elasticsearch 2 2 3 RELEASE 与 Elasticsearch v6 8 6 结合使用 我配置了 RestHighLevelClient 以连接到集群 现在我在
  • 如何在 React 中将 JSON 响应呈现为下拉列表

    我目前正在尝试获取从 API 收到的一些 JSON 数据 并将其放入一个非常简单的 React 应用程序的下拉列表中 到目前为止 这是我的 DropDown 组件 import React from react var values fet
  • 如何使用boost预处理器生成访问器?

    例如 class A int m x float m y double m z int x const return m x float y const return m y double z const return m z 变得像 cl