【问题标题】:C++ Macro ArithmetricC++ 宏算术
【发布时间】:2010-03-18 21:45:16
【问题描述】:

我必须处理宏(它是调用宏的宏;所以模板是不可能的)。

这就是我想要的:

foo(3, a, b1, c1) --> foo1(a, b1, c1);
foo(5, a, b1, c1, b2, c2) -> foo2(a, b1, c1, b2, c2);
foo(7, a, b1, c1, b2, c2, b3, c3) -> foo3(a, b1, c1, b2, c2, b3, c3);

所以基本上,我想要的是能够在宏扩展时执行“函数” n -> (n-1)/2 。这可能吗?

[PS,如果你不喜欢我的问题;我支持你投反对票的权利;到目前为止我最糟糕的问题只有-17,所以也许我们可以打破这个记录;但是,请告诉我为什么我的问题在技术上是无效的。]

编辑:

Foo 接受可变参数#,格式为:

foo(N, a1, b1, a2, b2, ... a_N, b_N) -> foo##N(a1, b1, a2, b2, ... a_N, b_N);

编辑:

致所有接近者。这是一个非常不同的问题。前者是关于“我如何计算宏中的参数数量”。 (邮件列表上有很好的回应)。

这个问题是这样的:鉴于我已经计算了参数的数量,我该如何调度它?

【问题讨论】:

  • 你想要这样的装置干什么?
  • 看起来像是 stackoverflow.com/questions/2473262/… 的稍微改写的副本。
  • 你在 my 不好的一面,因为 1) 你问了 很多 问题,提供的答案很少,并且为你提供的人获得的选票很少;但是您却提到了您正在从事的复杂项目 2) 您似乎无法或不愿意搜索 3) 您的问题往往不精确、模糊、没有上下文,并且不太可能帮助后来的任何人(这个问题是一个很好的例子) 和 4) 你没有表现出愿意为自己工作的迹象:而不是从你以前的帖子的副本中工作,你只是再次发布并希望我们会做你的工作。你可以而且应该做得更好。
  • 我休息一下。您在评论中不准确地描述的问题不是您在问题正文中不准确地描述的问题,而且您显然没有把“没有标准的方法来做 vararg marcos”放在心上,没有花任何时间试图理解任何特定的vararg 宏实现也没有说你将使用哪一个。顺便说一句,您的问题的答案是您在宏扩展时进行算术运算,您对代码进行纯文本重写。
  • @anon 我认为真正引起我们注意的是,当您提出问题时,您和回答者之间没有有用的对话,而且您的少数答案实际上是 cmets(而不是有帮助的人)。这是我的建议——花一个星期不问问题,并在那一周下决心回答至少三个。哦,换个昵称吧。

标签: c++ macros


【解决方案1】:

我没有对此进行测试,但应该可以:

#define SUBSTFOO3( a, b1, c1 ) foo1(a, b1, c1)
#define SUBSTFOO5( a, b1, c1, b2, c2 ) foo2(a, b1, c1, b2, c2)
/* ad nauseam */

#define foo( N, ... ) SUBSTFOO ## N ( __VA_ARGS__ )

这也可能有效:

#define SUBSTFOO3 foo1 /* no arguments needed */
#define SUBSTFOO5 foo2 /* "( __VA_ARGS__)" already the correct substitution */

#define foo( N, ... ) SUBSTFOO ## N ( __VA_ARGS__ )

【讨论】:

  • 可能需要更改为#define foo3( a, b1, c1 ) (foo1)(a, b1, c1) a) 去掉分号 b) 在函数名周围加上括号以防止意外的宏扩展(在foo3 的情况下)或类似错误。跨度>
  • 分号是对的,但我认为括号不会停止宏扩展。在这里偏执的方法是介绍你自己的#define foo3 foo3
  • (foo1)(a, b, c) 是为了防止 foo(7, ...) 简化为 foo7(a, b, c, d, e)foo3(a, b, c, d, e)error: macro "foo3" passed 7 arguments, but takes just 3(这是我使用 GCC 时得到的)。
  • @Chris:啊,我明白了。我认为更好的解决方案是首先避免混淆中间步骤的名称。更正我的答案。
【解决方案2】:

我不确定我是否理解您的问题,但这让我想起了我在 GCC 源代码中看到的这个诡计。也许你会发现一些适用的东西。

#if GCC_VERSION >= 3000 || __STDC_VERSION__ >= 199901L
/* Use preprocessor trickery to map "build" to "buildN" where N is the
   expected number of arguments.  This is used for both efficiency (no
   varargs), and checking (verifying number of passed arguments).  */
#define build(code, ...) \
  _buildN1(build, _buildC1(__VA_ARGS__))(code, __VA_ARGS__)
#define _buildN1(BASE, X)   _buildN2(BASE, X)
#define _buildN2(BASE, X)   BASE##X
#define _buildC1(...)       _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1,0,0)
#define _buildC2(x,a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c
#endif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 2012-07-27
    • 2014-09-12
    • 2017-10-27
    • 1970-01-01
    相关资源
    最近更新 更多