简体   繁体   English

C++ 替代预处理器#ifdef / #endif

[英]C++ alternative to pre-processor #ifdef / #endif

I have a StopWatch class which I use to measure execution time.我有一个 StopWatch 类,用于测量执行时间。 I instantiate several different stopwatches to log execution time by category.我实例化了几个不同的秒表以按类别记录执行时间。 For example:例如:

#ifdef EXEC_TIME_PROF
StopWatch func1sw;
StopWatch func2sw;
#endif

void foo() {
#ifdef EXEC_TIME_PROF
func1sw.start();
#endif

func1();

#ifdef EXEC_TIME_PROF
func1sw.stop();
func2sw.start();
#endif

func2();

#ifdef EXEC_TIME_PROF
func2sw.stop();
#endif
}

#ifdef EXEC_TIME_PROF
func1sw.logTime();
func2sw.logTime();
#endif

So the actual 2-line function becomes a lot longer and more cluttered with all the #ifdef statements.因此,实际的 2 行函数变得更长,而且所有的 #ifdef 语句都变得杂乱无章。 The reason that I use the #ifdef is because I don't want the statements to be compiled in a non-profiling / production build.我使用 #ifdef 的原因是我不希望在非分析/生产版本中编译语句。 Does anyone know a better way of doing this?有谁知道这样做的更好方法吗? My development environment is Windows / Visual Studio C++ 2015.我的开发环境是 Windows/Visual Studio C++ 2015。

You can just use the macro to switch between a class that does something and a class that does nothing at all.您可以使用宏在执行某些操作的类和根本不执行任何操作的类之间切换。 The compiler should recognize that and exclude it from compilation.编译器应该认识到这一点并将其排除在编译之外。

#ifdef EXEC_TIME_PROF

// your actual implementation
class StopWatch
{
    // ...
};

#else

// completely empty implementation
class StopWatch
{
public:
    void start() {}
    void stop() {}
    void logTime() {}
};

#endif

If you still want to use StopWatch for other things in production, then just use something else like ProfilingStopWatch roughly as follows:如果你仍然想在生产中使用StopWatch做其他事情,那么只需使用其他类似ProfilingStopWatch东西,大致如下:

#ifdef EXEC_TIME_PROF

typedef StopWatch ProfilingStopWatch;

#else

// completely empty implementation
class ProfilingStopWatch
{
public:
    void start() {}
    void stop() {}
    void logTime() {}
};

#endif

So, in case it's not completely clear, you can remove the other macro tests from your code and use the class normally:因此,如果不完全清楚,您可以从代码中删除其他宏测试并正常使用该类:

ProfilingStopWatch func1sw;
ProfilingStopWatch func2sw;

void foo()
{
    func1sw.start();
    func1();
    func1sw.stop();

    func2sw.start();
    func2();
    func2sw.stop();
}

func1sw.logTime();
func2sw.logTime();

Simply add some extra macros to wrap the stopwatches, eg:只需添加一些额外的宏来包装秒表,例如:

#define concat(a,b) a ## b

#ifdef EXEC_TIME_PROF
StopWatch func1sw;
StopWatch func2sw;

#define RUN_FUNC(funcName) \
    concat(funcName,sw).start(); \
    funcName(); \
    concat(funcName,sw).stop();

#else

#define RUN_FUNC(funcName) \
    funcName();

#endif

void foo() {
     RUN_FUNC(func1);
     RUN_FUNC(func2);
}

#ifdef EXEC_TIME_PROF
func1sw.logTime();
func2sw.logTime();
#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM