有可能在同一个字符序列上有一个类似函数的宏和一个类似对象的宏吗

Is it possible to have a function-like macro and an object-like macro over the same char sequence?

本文关键字:对象 一个 函数 字符 同一个 有一个 有可能      更新时间:2023-10-16

我的问题是——我试图制作一个堆检查器,用于测试和这个

a) 重载标准的全局new/delete运算符,以便它们让我的自定义类了解每个alloc和delete

b) 添加具有类似的签名的自定义新运算符

void* operator new(size_t size, const char* filename, const char* function, int line)

c) 制作一个宏,用我的新调用和给定的文件func&线路

#define new new(__FILE__, __FUNCTION__, __LINE__)
  • 这很好用,除了有人在类中使用自定义new或直接使用运算符new()的情况——这意味着我只能在标准C++库(functional、algo、string…)中加载后定义这个宏,因为他们做这些事情很重

d),所以我们想出了使用var arg宏的绝妙主意,这将解决的这些问题

#define new(...) new(__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__)
  • 这适用于最后一点中的所有有问题的情况,因为传递给new(someargs)或运算符new(size_t,someargs

  • 但是它不适用于最常见的仅调用的情况

int*ptr=新int;

  • ,因为new调用没有括号,因此它没有扩展为函数宏

这就引出了标题中提到的问题:有没有任何方法可以用宏来实现这一点,这样无论是在没有参数列表的情况下调用还是用参数列表调用,都可以替换原始代码中的相同字符序列?

在这种情况下,期望的结果是:

后面没有括号的new-new -> new(__file__, __func__, __line__)

后面有括号的new-new(args) -> new(args, __file__, __func__, __line__)

我意识到,这是一个试图重新定义同一个宏的明显例子,所以这应该是不可能的。我正在寻找一些预处理器的魔力,让我绕过这一点。

免责声明:我知道这很难看,我们实际上在c)中解决了这个问题,只是忽略了标准库news。但我确实花了一些时间研究这种可能性,如果有人有可能的话,我会感兴趣。

干杯!

___EDIT___请不要把注意力集中在我想要完成的事情上,只关注标题中的问题。堆检查器本身可以以各种符合标准的方式实现,但这不是其中之一:)我更好奇的是,使用预处理器可以在多大程度上改变语言。

问题是——我可以使用一些预处理器命令来为后面有括号和没有括号的同一序列实现不同的行为吗(也就是说,就像我有一个同名的类似函数和类似对象的宏一样)

感谢您的任何和所有答案:)

不,你不能。请参阅§16.3p2 C++标准的[cpp.replace](在其他版本和C标准的等效部分中发现类似的措辞;没有任何变化)(强调我的):

当前定义为类对象宏的标识符(见下文)可以由另一个#define预处理指令重新定义,前提是第二个定义是类对象宏定义替换列表是相同的,否则程序格式不正确。同样,当前定义为类函数宏的标识符(见下文)可以由另一个#define预处理指令重新定义,前提是第二个定义是具有相同数量和拼写的参数的类函数宏定义,并且两个替换列表相同,否则程序格式错误。

换句话说,宏标识符既像对象,也像函数,但同一标识符不能同时用于两者。

相关文章: