在if语句的条件部分中定义变量不允许比较其值。为什么?

时间:2013-06-03 08:48:57

标签: c++ variables if-statement standards

摘要

此问题与:Defining a variable in the condition part of an if-statement?有关。

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


简单示例

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

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的条件?根据我的测试,似乎两个选项都是相同的 - 对false0NULL,无论如何都进行了隐式检查。但它是否由标准保证?


真实世界的例子

好的,我无法针对某些自定义值检查新变量,但我可以将其与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会很长,而且我不想在它之前声明所有变量。

3 个答案:

答案 0 :(得分:3)

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

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

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

你不能把它放到if

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

答案 1 :(得分:3)

  

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

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

  

如果评估第一个条件怎么样?

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

  

但它是否符合标准?

是:

  

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

答案 2 :(得分: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 ))。