是否可以根据函数结果创建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似乎没有得到正确定义。
有没有更好的方法来实现这一目标?这甚至可能吗?我想尽可能在头文件中获取此屏幕高度信息,因为这是大量遗留代码的一部分。
答案 0 :(得分:5)
没有。在编译时,宏在编译时完全评估,至少是由预处理器,在实际代码编译之前,#if
等中的表达式必须是预处理器表达式。在程序运行之前,无法知道屏幕的高度。
答案 1 :(得分:2)
不,它无法完成。你期望如何制作编译时的设计,这取决于运行应用程序的屏幕的属性?在编译时你无法知道。
答案 2 :(得分:2)
实际函数通常只被称为运行时。甚至类似函数的事情,例如sizeof
(和generalized constant expressions - 感谢@Pubby注释)在预处理阶段之后由编译器评估。到目前为止,所有预处理器内容都已在代码中被替换 - 编译器不知道#if
之类的内容。因此,使用宏无法实现所需。
但是,对于模板,它是可能的。第二个想法,不是在这种情况下,因为直到运行时才能知道实际的屏幕高度。
您可以定义一个结构以包含坐标值作为常量,并将所有这些存储在地图或其他形式的集合中,然后在您知道实际屏幕高度时在运行时动态查找。
答案 3 :(得分: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)