2010-02-05 141 views
4

人能做到这一点:C++:一种在if语句中声明一个变量(或多个变量)的方法,该变量将变量定义和测试分隔开来?

case WM_COMMAND: 
if (WORD wNotifyCode = HIWORD(wparam)) 
{ 
    ... 
} 

而且可以做到这一点:

case WM_COMMAND: 
{ 
    WORD wNotifyCode = HIWORD(wparam); 
    if (wNotifyCode > 1) { 
    ... 
    } 
} 

但缺一不可:

case WM_COMMAND: 
if ((WORD wNotifyCode = HIWORD(wparam)) > 1) 
{ 
    ... 
} 

使用这里声明,我认为是一种误导:

case WM_COMMAND: 
for (WORD wNotifyCode = HIWORD(wparam); wNotifyCode > 1; wNotifyCode = 0) 
{ 
    ... 
} 

因为它看起来很像一个循环正在发生 - 而且跟在我后面的可怜的笨蛋必须破译这些垃圾。

但有它结合if语句,包括局部变量声明来测试它的值为零以外的东西的能力的优雅没有语法结构?

+3

你的第二个例子不可接受吗?我发现,无论是在范围和清晰度方面,都是最可取的。 – greyfade 2010-02-05 20:26:19

+0

这是我要去的人。我只是想避免为此创建一个任意的额外范围,当你几乎可以在if语句中这样做时(并且肯定可以用for表达式来完成)。如此接近......但是,额外的范围现在是一个实际的解决方案。 :) – Mordachai 2010-02-05 21:19:44

+0

据我所知,ATL/WTL有更好的(更多的OO)语法。你可能想考虑使用这些库。 – 2010-02-05 21:28:06

回答

3

有时可读性和可维护性比保存的一行代码更重要。

IF你需要的局部变量都然后通过各种手段在这种情况下,明确地介绍它,如果你希望它有限的,也许引进一个额外的范围 - 但你也应该考虑是否也许你可以使用的生活HIWORD宏在几个地方 - 这样你根本不需要任何技巧。

+0

再次 - C++允许我在由if自己定义的范围中声明该变量...因此,如果我可以设置测试条件而不是被迫用衰变来标量非零,我会得到所有可能世界中最好的。现在我将与额外的范围一起生活。 ;) – Mordachai 2010-02-05 21:21:43

-2

您可以修改您的测试了一下:

if (WORD wNotifyCode = HIWORD(wparam) - 1) 

,如果你想检查是否wNotifyCode > 1

+0

嗯,'!= 1'真的,但我想我们假设'WORD'就像'uint16_t'?无论如何,我喜欢这个聪明点,尽管下面的代码块中的代码必须小心,'wNotifyCode'与本来的代码完全不同。 – ephemient 2010-02-05 19:59:53

+0

!= 1? OP样本是'> 1',这就达到了。是的,当然,你需要在脑海中一个人。 – dirkgently 2010-02-05 20:06:25

+0

事实上 - 这使得wNotifyCode =一个小于它应该的值,这不是我所希望的。 – Mordachai 2010-02-05 20:06:47

-2

我下面的作品

if (WORD nNotifyCode = HIWORD(test) > 1) 
{ 
} 

我大胆猜测,但不知道是肯定的,即=运算符的优先级高于>运营商,我知道了结局的赋值操作是作业的价值,测试起作用。

编辑: [上刊登戴高帽,去角]

+0

您的猜测是错误的。你写的东西被解释为'if(WORD nNotifyCode =(HIWORD(test)> 1))',这不是预期的。赋值运算符(以及相关的运算符,如+ =)具有所有运算符的最低优先级。它们只比抛出和(逗号)更高。 – 2010-02-05 19:50:55

+0

Doh - 测试的方式太快。今天的又一课。 – Ruddy 2010-02-05 19:52:21

+0

这是错的。这会将布尔表达式'HIWORD(test)> 1'应用于'wNotifyCode',结果为0或1.不是他所期望的。 – AndiDog 2010-02-05 19:52:33

1

预处理招数:

#define IF_2(init, test) \ 
    for (bool first_ = true; first_;) for (init; first_ && (test); first_ = false) 

IF_2(WORD wNotifyCode = HIWORD(wparam), wNotifyCode > 1) 
{ 
    ... 
} 

这是丑陋的,当然也没有比你已经有了更好的选择。

+0

我更喜欢所有大写的宏;可读性,减少错字的机会。 – dirkgently 2010-02-05 19:59:05

+0

对不起,但-1代表魔法和无法读取的代码:/ - 看起来这不能很好地完成,所以也许最好不要这样做? ;) – RnR 2010-02-05 20:11:33

+1

Upvote因为作者都回答了如何去做,并表示他们不建议这样做。记住人们:C++/C宏是邪恶的!强烈地考虑你的成本/收益,并且洗你的手两次:) – 2010-02-05 21:24:58

1

尝试引入一个辅助函数是这样的:

template <typename T> 
T zeroIfLess(T val, T base) 
{ 
    return val < base ? T(0) : val; 
} 

然后,写你的条件为:

if (WORD wNotifyCode = zeroIfLess(HIWORD(wparam), 2)) 

这将返回零 - 或者,如果你愿意, - 如果第一次提供的值小于第二次;否则它返回值。鉴于很难解决函数的名称,是否应该采取包容性或专有的最小化,它在这里工作并不会减少它是一个奇怪的黑客。

和其他人一样,我也赞成你的第一个建议,在“一个人可以做到这一点”之后 - 单独的声明和初始化语句后跟条件语句。我认为这只是在C++中实现它的自然方式。

1

提示:你可以使用消息破解宏;通过这种方式,你会得到一个短得多的wndproc(没有所有的嵌套开关),你的消息处理代码将被整齐地分割成单独的函数(每个消息一个函数),而你几乎不需要所有的HIWORD-LOWORD东西,因为信息破解宏为你做了这件事,并将lParam和wParam检索到的信息传递给你已经在参数中分割的函数。

+0

没有听说过“消息破解宏”。这些是你在说什么吗? http://support.microsoft.com/kb/83456 – 2010-02-05 21:28:44

+0

是的,他们是;在这里(http://www.codeproject.com/KB/winsdk/msgcrackwizard.aspx)你可以找到一些关于它们的介绍和一个帮助你的工具(关于它我一无所知)。 – 2010-02-05 21:56:42

+0

信息破解者可以非常有用。在我的具体情况中,我已经使用MFC来分解消息处理程序 - 但希望在给定的上下文中为通知类消息插入一个“泵阻塞程序”。所以我标记上下文,然后不传播旧的WM_COMMAND *通知*和新的WM_NOTIFY通知,但允许所有其他消息通过正常的消息映射分布处理程序。因此,在这个层面再次破除这些信息将会使这里的实际目的/架构混淆不清。一般来说,使用它们仍然是一个好主意! :) – Mordachai 2010-02-08 16:56:11