我有点困惑为什么会在语言中提供它,因为它似乎是可以应用于本不应该工作的代码的补丁。我很难想象它可以被用于一个不过度复杂(需要重构)的地方。
如果可以,请有人解释一下此语言功能的目的以及它在真实代码中可能的用途(合理范围内)。
这在 while()
循环的条件中可能很有用:
while (update_thing(&foo), foo != 0) {
/* ... */
}
这样可以避免重复使用update_thing()
代码行,同时仍然在while()
控制表达式中保持退出条件,这也是你期望找到的地方。它还与continue;
很好地配合使用。
这也适用于编写评估为值的复杂宏。
while (update_thing(y), test_thing(y))
。它允许你将更新和测试分开成两个单独的函数以提高可读性,并且在循环中仍然可以理解 -- 当(等等,让我们更新这个东西,好的现在--)这个东西测试为真时,执行这些操作。 - anon (x) (y)
for (int i = 0, j = 0; ...; ++i, ++j)
x
不是逗号运算符,但y
是。在 for
循环结构内使用它是有意义的。但我通常发现在这种情况下更难阅读。
这也是激怒你的同事和 Stack Overflow 上的人的好方法。
bool guess() {
return true, false;
}
while (foo) a, b, c;
的结构是清晰的,但是在缺少缩进或大括号的情况下,while (foo) a; b; c;
是具有误导性的,或者两者都缺失。
编辑 #2:正如AndreyT所述:
但他声称“实际上语句编程产生的可读代码要多得多” [已加重音] 明显是错误的。使用他的例子,你认为以下哪一行更易读?[C语言](以及C ++)历史上是两种完全不同的编程风格的混合,可以将其称为“语句编程”和“表达式编程”。
a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b;
回答: 它们都难以阅读。是空格使得内容易读 - Python太棒了!第一个更短。但分号版本有更多的黑色空间或者绿色空间(如果你使用Hazeltine终端)- 这可能是真正的问题?for (;;)
后面紧跟着a、b、c;
,很清晰易懂;但第二个例子for (;;) a; b; c;
在缺少缩进或括号的情况下可能会让人产生错误理解。 - Joseph Quinsey大家都说常常在for循环中使用它,这是真的。然而,我认为在for循环的条件语句中更加有用。例如:
for (int x; x=get_x(), x!=sentinel; )
{
// use x
}
如果不使用逗号运算符来重写这段代码,至少需要做以下几件事情,而这些事情都让我有些不太舒服,比如将变量x声明在它被使用的作用域之外,或者特殊处理对get_x()
的第一次调用。
同时,我在考虑如何在C++11的constexpr函数中利用逗号运算符,因为我猜想这些函数只能由单个语句组成。
(x=get_x())!=sentinel
,但我认为你的方式更清晰。 - lhf我认为唯一常见的例子就是for循环:
for (int i = 0, j = 3; i < 10 ; ++i, ++j)
有时候,你会发现自己处于这样一种情况:C语言需要一个表达式,但你却有两个想要表达的东西。最常见(实际上也是唯一常见)的例子就是在for循环中,特别是第一个和第三个控制表达式。
i
和j
的声明放在for循环外面(就像在C
中一样),只留下双重初始化。 - 6502for
结构中。for (int count=0, bit=1; count<10; count=count+1, bit=bit<<1)
{
...
}
因为它允许同时增加多个变量,仍然保持for
结构的形式(对于训练有素的人来说易于阅读和理解)。
在其他情况下,我同意这是一种不好的hack...
count = count + 1
?bit = bit << 1
? - Seth Carnegiecount++,bit<<=1
,但我认为这种方式更易读。 - 6502#define WARN if (++nwarnings, show_warnings) std::cerr
这样你就可以编写(示例1):
if (warning_condition)
WARN << "some warning message.\n";
逗号运算符实际上是一个穷人的 Lambda 函数。
我也使用逗号运算符将相关操作粘合在一起:
void superclass::insert(item i) {
add(i), numInQ++, numLeft--;
}
,
被替换为;
,会有什么不同吗?虽然看起来略有不同,但在这种情况下,“粘合在一起”的意思是什么? - TobiMcNamobiwhile (1) ++i, ++j
。粘合在一起意味着逻辑上将这些语句分组,以便清楚地表明这些操作紧密相关。 - perreal尽管是在C++11被批准几个月后发布的,但我没有看到与constexpr
函数相关的任何答案。这个答案对一个不完全相关的问题进行了引用,提到了逗号运算符及其在常量表达式中的有用性,新的constexpr
关键字特别被提到。
虽然C++14放宽了一些constexpr
函数的限制,但仍然值得注意的是,逗号运算符可以在constexpr
函数中为您提供可预测的有序操作,例如(来自上述讨论):
template<typename T>
constexpr T my_array<T>::at(size_type n)
{
return (n < size() || throw "n too large"), (*this)[n];
}
甚至可以是这样的:
constexpr MyConstexprObject& operator+=(int value)
{
return (m_value += value), *this;
}
这是否有用完全取决于实现,但这只是两个快速示例,说明逗号运算符如何在constexpr
函数中应用。