如何计算宏执行次数?

时间:2011-12-01 09:19:07

标签: c++

我有两个声明类属性的宏:

DECLARE_QUERY_PARAM_LONG(name)
DECLARE_QUERY_PARAM_STRING(name)

我想计算我的类和init中的这些宏的调用次数

static const size_t paramsCount 

用这样的数字:

class MyClass {
...

    DECLARE_QUERY_PARAM_LONG(param1)
    DECLARE_QUERY_PARAM_STRING(param2)
    DECLARE_QUERY_PARAM_STRING(param3)
    DECLARE_QUERY_PARAM_LONG(param4)

    static const size_t paramsCount = PARAMS_COUNT; // 4 in this case

...
};

这有可能吗?

6 个答案:

答案 0 :(得分:5)

会有一个解决方案,相当复杂:

  1. 您的所有参数都有固定名称(例如 param
  2. 您需要为每种类型创建一个头文件
  3. 你需要提升
  4. 所以这是标题创建文件:

    // file declare_int.h
    
    #include BOOST_PP_UPDATE_COUNTER()
    
    int stringize(param,BOOST_PP_COUNTER) ;
    

    和类文件:

    //file declare_auto.cpp
    #include <boost/preprocessor/slot/counter.hpp>
    
    #define _stringize(a,b) a##b
    #define stringize(a,b) _stringize(a,b)
    
    // reset counter
    #if defined(BOOST_PP_COUNTER)
    #undef BOOST_PP_COUNTER
    #endif
    
    class A {
    public:
    
    #include "declare_int.h"
    #include "declare_int.h"
    #include "declare_int.h"
    #include "declare_int.h"
    
    static const int nbParams = BOOST_PP_COUNTER ;
    };
    

    最后输出:

      

    g ++ -E -P -c declare_auto.cpp -IPATH_TO_BOOST

    class A {
    public:
    int param1 ;
    int param2 ;
    int param3 ;
    int param4 ;
    static const int nbParams = 4 ;
    };
    

答案 1 :(得分:4)

您至少可以通过以下方式计算行数:

class MyClass
{
    static const int line_1 = __LINE__;
    DECLARE_QUERY_PARAM_LONG(param1)
    DECLARE_QUERY_PARAM_STRING(param2)
    DECLARE_QUERY_PARAM_STRING(param3)
    DECLARE_QUERY_PARAM_LONG(param4)
    static const int line_2 = __LINE__;
    static const int macro_calls = line_2 - line_1 - 1;

public:
    MyClass()
    {
        cout << macro_calls << endl;
    }
};

但我认为你需要C ++ 11才能做到这一点。并且在这两个__LINE__中你不能有空行。否则,你也必须计算那些空行。

答案 2 :(得分:2)

因此没有。

您要求的内容需要某种形式的内省,而C ++本身并不支持。

如果你有:

,你可以改进宏
DECLARE_QUERY_PARAMS(((LONG  , param1))
                     ((STRING, param2))
                     ((STRING, param3))
                     ((LONG  , param4)))
然后你可以做你想做的事。

您可以查看Boost.Preprocessor,了解如何以这种方式对源进行模糊处理。

注意:这使用序列,用激励术语。

答案 3 :(得分:2)

我认为没有一种标准方法可以做到这一点,但DevStudio编译器有这个预处理器宏:

  

__ COUNTER __

     

扩展为以0开头的整数,并在每次在compiland中使用时递增1。 __COUNTER__在使用预编译头时会记住它的状态。如果在构建预编译头(PCH)后最后一个__COUNTER__值为4,则在每次使用PCH时它将从5开始。

     

__ COUNTER__允许您生成唯一的变量名称。您可以使用带前缀的令牌粘贴来创建唯一名称。例如:

// pre_mac_counter.cpp
#include <stdio.h>
#define FUNC2(x,y) x##y 
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)

int FUNC(my_unique_prefix);
int FUNC(my_unique_prefix);

答案 4 :(得分:1)

没有。宏根本不尊重范围,也不理解他们在课堂上。

答案 5 :(得分:0)

没有。宏不会被执行,它们会被扩展,甚至不是由编译器扩展,而是由预处理器扩展。