1

概括

这个问题与:在 if 语句的条件部分定义变量?.

那么,为什么我不能在同一个地方检查新定义的变量的值呢?


简单的例子

换句话说,这是允许的(来自链接的问题):

if( int* x = new int( 20 ) ) 
{   
    std::cout << *x << "!\n";
    delete x;
}   

但这不是:

if( NULL != ( int* x = new int( 20 ) ) )
{   
    std::cout << *x << "!\n";
    delete x;
}   

第二个给我:

test.cpp:xx: error: expected primary-expression before ‘int’
test.cpp:xx: error: expected ‘)’ before ‘int’

问题

并且(也许)这里更重要的问题 - 第一个的条件是如何if评估的?根据我的测试,这两个选项似乎都做同样的事情 - 隐式检查false( 0, NULL, 不管)。但标准能保证吗?


真实世界的例子

好的,我无法根据某些自定义值检查新变量,但我可以将其与false. 所以,这是一个真实的例子:我有一个类,包含一个template方法:check_class。此方法执行dynamic_cast一个内部指针。现在我想像这样使用它:

if( some_class* some_class_ptr = cmd->check_class< some_class >() )
{
     // some_class_ptr is NOT NULL here
}
else if( other_class* other_class_ptr = cmd->check_class< other_class > )
{
    // other_class_ptr is NOT NULL here
}
// ...

想要这个的原因是它if会很长,我不想在它之前声明所有变量。

4

3 回答 3

3

原因在于语言的语法。简而言之,if条件(和类似的结构)中的代码可以是声明或表达式。当它是一个声明时,当然没有语法可以将声明的实体与某物进行比较。

当它是一个表达式时,它就像代码中其他任何地方的任何其他表达式。就像你不能这样写:

int foo() {
  bar(4 + (int b = 7));
}

您不能将其放入if.

为什么它可以与比较对象进行比较,true因为当 中的代码if是声明时,条件被评估为“声明的对象上下文转换为布尔值”。

于 2013-06-03T08:55:53.433 回答
3

那么,为什么我不能在同一个地方检查新定义的变量的值呢?

因为语法不允许。条件可以是声明表达式。表达式不能声明命名变量,声明不能用作表达式。

如果评估,第一个条件如何?

变量被初始化,其值转换为bool. 如果产生 ,则条件成功true

但标准能保证吗?

是的:

C++11 6.4/3 在语句以外的switch语句中作为初始化声明的条件的值是上下文转换为的声明变量的值bool

于 2013-06-03T08:57:12.623 回答
0

第一个的条件如何if评估?

正如你所想的那样。以下

if( int* x = new int( 20 ) ) 
{   
    std::cout << *x << "!\n";
    delete x;
}   

“大致”相当于

{
   int* x = new int( 20 );
   if( x ) 
   {   
       std::cout << *x << "!\n";
       delete x;
   }   
}

并且在测试if( x )中,表达式x被隐式转换为bool,这意味着if( x != 0 )(或if( x != NULL ))。

于 2013-06-03T08:55:27.330 回答