2012-03-23 91 views
2

是否可以基于函数结果创建C++预处理器宏?有没有办法为函数创建一个预处理宏?

例如,我希望动态保存屏幕高度的预处理宏定义:

#define SCREEN_HEIGHT GetSystemMetrics(SM_CYVIRTUALSCREEN) 

然后我想使用该结果基于屏幕高度设定值:

#if SCREEN_HEIGHT < 1200 
    #define TOP_COORD  200 
    #define BOTTOM_COORD 500 
    #define LEFT_COORD 0 
    #define RIGHT_COORD 1280 
#else 
    #define TOP_COORD  1100 
    #define BOTTOM_COORD 1400 
    #define LEFT_COORD 0 
    #define RIGHT_COORD 1280 
#endif 

这不起作用,因为SCREEN_HEIGHT似乎没有得到正确定义。

有没有更好的方法来实现这个目标?这甚至有可能吗?如果可能,我希望能够在头文件中获得此屏幕高度信息,因为这是大量遗留代码的一部分。

回答

5

编号宏在编译时被完全评估,在实际代码被编译之前,至少在预处理器的概念上是完全评估的,并且#if等中的表达式必须是预处理器表达式。在程序运行之前,不能知道屏幕的高度。

+0

非常好,谢谢。 – devurs 2012-03-23 17:00:13

2

不,不能这样做。您如何期望编译时间的设定,取决于应用程序运行的屏幕属性?在编译时你无法知道。

2

实际功能通常只会被调用运行时。偶函数状的东西,如sizeof(和generalized constant expressions - 由于@Pubby用于指出)是由编译器预处理阶段后进行评价。到目前为止,所有预处理器的东西都已被代码替换 - 编译器不知道诸如#if之类的东西。因此,你想要的是不可能使用宏。

有了模板,但是,它是可能的。 第二个想法,不是在这种情况下,因为直到运行时才能知道实际的屏幕高度。

你可以定义一个struct包含的坐标值作为常量,而所有这些存储在地图或收集的其他形式,然后看看它在运行时动态,当你知道实际的屏幕高度。

+1

函数可以在编译时调用。 – Pubby 2012-03-23 17:01:46

+0

@Pubby,谢谢,我不知道。添加了相应文章的链接。 – 2012-03-23 17:06:28

0

如果GetSystemMetrics将是一个宏,那么你可以做到这一点。 如果GetSystemMetrics将是constexpr,那么你可以使用特质。

但由于GetSystemMetrics是一个正常的功能,你有正常的C++工作。

struct system_metrics_ { 
    int top, bottom, left, right; 

    system_metrics_() 
    { 
    if (GetSystemMetrics(SM_CYVIRTUALSCREEN) < 1200) { /* first case */ } 
    else { /* second case */ } 
    } 
}; 

// define this method outside the header 
const system_metrics_& system_metrics() { static system_metrics_ sm; return sm; } 

// legacy code 
#define TOP_COORD  (system_metrics().top) 
#define BOTTOM_COORD (system_metrics().bottom) 
#define LEFT_COORD (system_metrics().left) 
#define RIGHT_COORD (system_metrics().right) 
相关问题