【问题标题】:Reusable preprocessor __COUNTER__可重用的预处理器 __COUNTER__
【发布时间】:2011-06-10 19:30:05
【问题描述】:

我正在做一些模板元编程,主要是编写我自己的编译时间列表,但我也有一些预处理器魔法,如果可能的话,我想用它来让事情变得更容易。

我要做的是创建一个仿函数的编译时间列表。该部分已完成,但用于简化创建(并添加到列表)的宏尚未完成。

一个简单的例子:

template<typename Functor, typename Tail>
struct node {
    typedef Functor head;
    typedef Tail tail;
};


template <typename Functor, typename Tail>
struct push_back {
    typedef node<Functor, Tail> list;
};

struct unit0 {};

#define AUTO_FUNCTION(name) struct test_functor_##name {            \
    static void run_test();                                         \
};                                                                  \
typedef push_back<                                                  \
            test_functor_##name,                                    \
            CONCAT(unit, PP_DEC(__COUNTER__))                       \
        >::list CONCAT(unit, __COUNTER__);                          \
void test_functor_##name::run_test()


AUTO_FUNCTION(hello) {
    ...
}

现在,这行得通,因为我为 PP_DEC 创建了一大组预处理器宏,即:

#define PP_DEC(x) PP_DEC_I(x)
#define PP_DEC_I(x) PP_DEC_ ## x
#define PP_DEC_1 0
#define PP_DEC_2 1
...
#define PP_DEC_N N

这是我真正想要避免的部分,也是我提出这个问题的原因。有没有人建议我如何使用 COUNTER 而不会增加其价值,或者我可以通过其他方式完成类似于以下的计数模式:

 0 1
 1 2
 2 3
 ...

改变push_back等语义的建议当然也欢迎:)。

PS。这不是为了生产,只是为了好玩。所以欢迎 GCC 特定的扩展。

PPS。我试图避免外部依赖,例如 boost,因为我想了解我正在做的一切(这个项目的全部意义)。

【问题讨论】:

  • __COUNTER__ 是 Microsoft 语言扩展,而不是标准 C++
  • @Alf P. Steinbach - 我知道。不过,它确实存在于 GCC 4.3 和 clang 中,因为我真的不介意为此使用编译器特定的扩展(因为它只是为了好玩),所以使用了 __COUNTER__。当然欢迎任何其他在没有__COUNTER__ 的情况下完成类似事情的建议。
  • 我遇到了类似的问题 - 你解决了吗?谢谢。 =)

标签: c++ templates c-preprocessor


【解决方案1】:

您可以使用额外的宏“修复”__COUNTER__ 值:

#define MY_MACRO MY_MACRO_COUNTED(__COUNTER__)

#define MY_MACRO_COUNTED(counter) counter + counter

【讨论】:

  • 真的有效吗?我进行了测试,每次调用 MY_MACRO 时都会得到不同的值。
  • @Phillip 您每次调用 MY_MACRO 时都应该得到不同的值。问题是counter value inside 宏应该是相同的,即使它被多次使用。 IE。每次扩展宏时,__COUNTER__ 都会有所不同,因此您会得到不同的结果。 “修复”只是解决了宏扩展期间__COUNTER__ 的使用问题 - 没有它,__COUNTER__ 的值每次在宏主体中引用时都会有所不同。
  • 您能否举例说明如何在宏中使用两次?
  • @TorKlingberg 在上面的示例中,它在#define MY_MACRO_COUNTED(counter) counter + counter 中使用了两次——所以(我猜)MY_MACRO 的每次调用都应该有效地返回2 * (initial value of) __COUNTER__,而不是2 * (initial value of) __COUNTER__ + 1,如果@987654332 @ 在#define MY_MACRO __COUNTER__ + __COUNTER__ 中直接使用。
猜你喜欢
  • 2011-10-20
  • 1970-01-01
  • 2010-10-13
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2011-03-26
  • 1970-01-01
相关资源
最近更新 更多