2012-07-17 65 views
1
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.如果只有if (int* p = bar())一切工作正常。为什么这个“如果” - 陈述工作?

我知道我可以在if之前初始化p -statement,但我对显示的变体感兴趣。

回答

2

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()) 

,直接初始化是不允许的)

+0

谢谢你的回答。 – fogbit 2012-07-17 10:53:22

-1

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

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

希望这有助于

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

首先评估逻辑表达式,然后分配

相同写作:

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

什么是“另一种变体”我放在代码? – fogbit 2012-07-17 10:29:10

+0

@forgbit:我会优先考虑if(bar()&& foo()){}'。请记住,简单比复杂更好 – Andrew 2012-07-17 10:32:47

+0

我也会,但如果你像我展示的框架一样给予什么?当你必须将第一个函数的结果作为输入参数传递给第二个函数时? – fogbit 2012-07-17 10:38:00

3

赋值运算=具有比布尔和&&较低的优先级从而什么你有这样的:

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

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

编辑:虽然它通常是一个公认的做法来声明和初始化变量,在环的块(如for(int i = 0; i < n; ++i))我会强烈建议不要如此构建的条件语句,像if()因为它可能会导致一些非常有趣的侧 - 您实际上不想处理的影响以及降低代码的可读性。

你的另一变化应该工作(除非我不知道你想declaraion int*...的结果比较空 - 这可能不是由语言很喜欢),但见上约代码清晰我的评论

+0

那么我放置在代码中的“另一个变体”呢?你能说出为什么它不起作用吗? – fogbit 2012-07-17 10:29:37

+0

避免在'if()'语句中声明变量,你应该没问题:) – YePhIcK 2012-07-17 10:32:37

+0

你能举一个副作用的例子吗?而我的其他变体不起作用,在VS2008的标识符'p'''和GCC中出现类似的错误之前,我得到''错误C2146:syntax error:missing')''。你能告诉你使用的压缩机吗? – fogbit 2012-07-17 10:34:01

0

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

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

但你的意思是要执行什么,我相信是:

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

这是不完全一样的。

2
#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; 
} 

OR

int main() { 

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

它运行

+0

我做了,我得到了''错误C2146:语法错误:缺少')'在VS2008中的标识符'p'''之前 – fogbit 2012-07-17 10:26:25

+0

@fogbit你有没有试过这个? – Pooya 2012-07-17 10:47:45

+0

这有效,尽管这不是我想要的,但谢谢你的回答! – fogbit 2012-07-17 11:01:20

2

一个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 
    } 
} 
+0

谢谢你的解释,现在看起来很清楚。 – fogbit 2012-07-17 10:52:53