Joe*_*der 165 c++ comma-operator
逗号运算符如何在C++中工作?
例如,如果我这样做:
a = b, c;  
最终是否等于b或c?
(是的,我知道这很容易测试 - 只是在这里记录,以便有人快速找到答案.)
更新: 此问题在使用逗号运算符时暴露了细微差别.只是记录下来:
a = b, c;    // a is set to the value of b!
a = (b, c);  // a is set to the value of c!
这个问题实际上是受到代码中的拼写错误的启发.打算做什么
a = b;
c = d;
转换成
a = b,    //  <-  Note comma typo!
c = d;
Kon*_*lph 127
请注意,逗号运算符可能在C++中过载.因此,实际行为可能与预期的行为非常不同.
例如,Boost.Spirit非常巧妙地使用逗号运算符来实现符号表的列表初始值设定项.因此,它使以下语法成为可能且有意义:
keywords = "and", "or", "not", "xor";
请注意,由于运算符优先级,代码(故意!)相同
(((keywords = "and"), "or"), "not"), "xor";
也就是说,第一个被调用的运算符是keywords.operator =("and")返回一个代理对象,在该代理对象上operator,调用其余的s:
keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");
efo*_*nis 122
逗号运算符具有所有C/C++运算符的最低优先级.因此,它始终是绑定到表达式的最后一个,这意味着:
a = b, c;
相当于:
(a = b), c;
另一个有趣的事实是逗号运算符引入了一个序列点.这意味着表达式:
a+b, c(), d
保证按顺序评估其三个子表达式(a + b,c()和d).如果它们有副作用,这是很重要的.通常,编译器可以按照他们认为合适的顺序评估子表达式; 例如,在函数调用中:
someFunc(arg1, arg2, arg3)
可以按任意顺序评估参数.请注意,函数调用中的逗号不是运算符; 他们是分隔符.
Cyg*_*sX1 63
逗号运算符:
为所有类型(内置和自定义)定义了默认版本的逗号运算符,它的工作方式如下 - 给定exprA , exprB:
exprA 被评估exprA被忽略了exprB 被评估exprB被返回作为整个表达式的结果对于大多数运算符,允许编译器选择执行顺序,如果它不影响最终结果,甚至需要跳过执行(例如,false && foo()将跳过调用foo).然而,这不是逗号运算符的情况,并且上述步骤将始终发生*.
实际上,默认的逗号运算符的工作方式与分号几乎相同.不同之处在于,由分号分隔的两个表达式形成两个单独的语句,而逗号分隔将所有表达式保留为单个表达式.这就是为什么逗号运算符有时用于以下场景:
if( HERE )for循环的初始化中for ( HERE ; ; )if (foo) HERE ;请不要这样做,它真的很丑!)如果语句不是表达式,则分号不能用逗号替换.例如,这些是不允许的:
(foo, if (foo) bar)(if不是表达)在您的情况下,我们有:
a=b, c;,相当于a=b; c;,假设该a类型不会使逗号运算符超载.a = b, c = d;相当于a=b; c=d;,假设该a类型不会使逗号运算符重载.请注意,并非每个逗号实际上都是逗号运算符.一些逗号含义完全不同:
int a, b; ---变量声明列表以逗号分隔,但这些不是逗号运算符int a=5, b=3; ---这也是一个逗号分隔的变量声明列表foo(x,y)---以逗号分隔的参数列表.事实上,x并且y可以在被评估的任何命令!FOO(x,y) ---逗号分隔的宏参数列表foo<a,b> ---逗号分隔的模板参数列表int foo(int a, int b) ---逗号分隔的参数列表Foo::Foo() : a(5), b(3) {} ---类构造函数中的逗号分隔的初始化列表*如果您应用优化,则不完全正确.如果编译器认识到某段代码对其余代码完全没有影响,它将删除不必要的语句.
进一步阅读:http://en.wikipedia.org/wiki/Comma_operator
Mob*_*yDX 37
值a将是b,但表达式的值将是c.也就是说,在
d = (a = b, c);
a等于b,d等于c.