繁体   English   中英

为什么这种“如果”声明不起作用?

[英]why doesn't this “if”-statement work?

bool foo( int* p )
{
  return false;
}

int* bar (  )
{
  int* p;
  return p;
}

int main() {

  if ( int* p = bar() && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {

  }

  return 0;
}

我收到error: cannot convert 'bool' to 'int*' in initialization使用GCC 4.3.4和VS 2008 error: cannot convert 'bool' to 'int*' in initializationerror: cannot convert 'bool' to 'int*' in initialization 。如果只有if ( int* p = bar())一切正常。

我知道我可以初始化p之前if语句来,但我很感兴趣,我所示的变型。

int* p = bar() && foo( p )

首先计算逻辑表达式,然后赋值

与写作相同:

int *p = ( bar() && foo(p) );

赋值运算符=的优先级比布尔和&&的低,因此您拥有的是:

int* p = ( bar () && foo(p) )

试图将bool分配给int*变量。

编辑 :虽然在循环块中声明和初始化变量是一种普遍接受的做法(例如for(int i = 0; i < n; ++i) ),但我强烈建议不要使用这种条件语句构造,例如if()因为它可能会导致一些您确实不想处理的非常令人着迷的副作用,并且降低了代码的可读性。

您的其他变体应该可以正常工作(除非我不确定您是否要将declaraion int*...的结果与NULL进行比较-该语言可能不喜欢NULL),但是请参阅上面有关代码清晰度的评论

#include <iostream>
bool foo( int* p )
{
  return false;
}

int* bar (  )
{
  int* p;
  return p;
}

int main() {
  int* p;
  if ( (p = bar()) && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {

  }

  return 0;
}

要么

int main() {

  if ( int* p = bar()){
      if ( foo( p ) ){ /*do something*/ }
  }
  return 0;
}

它运行

一个的条件if语句可以声明表达式。 声明不是表达式,因此您无法在尝试将其与另一个表达式结合使用。 换句话说,当你希望

(int* p = bar()) && foo(p)

这是无效的,因为int* p = bar()不是表达式。 相反,它被视为声明

int* p = (bar() && foo(p))

无效,因为初始化程序的类型错误。

在这种情况下,您将不得不在if语句之前声明指针; 有两种选择:

int* p = bar(); // pollutes surrounding scope; maybe wrap in another block
if (p && foo(p)) {}

if (int* p = bar()) {
    if (foo(p)) {  // extra nesting
    }
}

if的语法在括号中需要一个条件 条件可以是表达式或声明(具有隐式转换为bool的类型); 它不能是这些的组合。 如果是

if ( int* p = bar() && foo( p ) )

条件是“ int* p = bar() && foo( p ) ”,它是用bar() && foo( p )初始化的int*类型的简单声明; 由于bar() && foo( p )类型不是int* ,并且不能隐式转换为int* ,因此您会遇到错误。

如果您写:

if ( (int* p = bar()) != NULL )

,左括号表示这不能是声明(简单或否),并且int* p = bar()不是合法的(子)表达式。

关键的一点要记住的是,你可以有一个声明, 或者你可以有一个表达,但你不能将它们组合起来,和C ++不允许声明作为表达的一部分。 (另外:声明必须具有副本初始化:

if ( int* p = bar() )

,则不允许直接初始化。)

我相信这是运营商的优先事项。 您实际上执行:

if ( int* p = (bar() && foo( p )) )

但是我相信您要执行的意思是:

if ( (int* p = bar()) && foo( p ) )

这不完全相同。

事实是您正在使用int* p = bar()进行赋值,并且该语句尝试比较两种类型: intbool ,这是不可能的。

您应该在IF语句之前分配它。

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM