我经常看到关于在 C++ 中重载逗号运算符的问题(主要与重载本身无关,但与序列点的概念类似),这让我想知道:
什么时候你应该重载逗号?其实际用途有哪些例子?
我只是想不出任何我
foo, bar;
在现实世界代码中见过或需要的例子,所以我很好奇什么时候(如果有的话)实际使用它。
I see questions on SO every so often about overloading the comma operator in C++ (mainly unrelated to the overloading itself, but things like the notion of sequence points), and it makes me wonder:
When should you overload the comma? What are some examples of its practical uses?
I just can't think of any examples off the top of my head where I've seen or needed to something like
foo, bar;
in real-world code, so I'm curious as to when (if ever) this is actually used.
发布评论
评论(11)
我使用逗号运算符来索引具有多个索引的映射。
请参阅 有关逗号运算符的 cpp 参考文章。
I have used the comma operator in order to index maps with multiple indices.
See the cppreference article on the comma operator.
让我们稍微改变一下重点:
答案是:从来没有。
例外:如果您正在进行模板元编程,
操作符
在操作符优先级列表的最底部有一个特殊的位置,它可以在构造 SFINAE-guards 等时派上用场。唯一的两个我见过的重载
operator,
的实际用途都在Boost中:Let's change the emphasis a bit to:
The answer: Never.
The exception: If you're doing template metaprogramming,
operator,
has a special place at the very bottom of the operator precedence list, which can come in handy for constructing SFINAE-guards, etc.The only two practical uses I've seen of overloading
operator,
are both in Boost:Boost.Assign 使用它,让您做这样的事情:
我已经看到它用于奇怪的语言黑客,我会看看是否能找到一些。
啊哈,我确实记得其中一个奇怪的用途:收集多个表达式。 (警告,黑魔法。)
Boost.Assign uses it, to let you do things like:
And I've seen it used for quirky language hacks, I'll see if I can find some.
Aha, I do remember one of those quirky uses: collecting multiple expressions. (Warning, dark magic.)
逗号有一个有趣的属性,它可以采用
void
类型的参数。如果是这种情况,则使用内置逗号运算符。当您想要确定表达式是否具有 void 类型时,这很方便:
我让读者作为练习弄清楚发生了什么。请记住,
运算符
与右侧关联。The comma has an interesting property in that it can take a parameter of type
void
. If it is the case, then the built-in comma operator is used.This is handy when you want to determine if an expression has type void:
I let the reader figure out as an exercise what is going on. Remember that
operator,
associates to the right.类似于 @GMan 的 Boost.Assign 示例,Blitz++ 重载逗号运算符以提供 用于处理多维数组的便捷语法。例如:
Similar to @GMan's Boost.Assign example, Blitz++ overloads the comma operator to provide a convenient syntax for working with multidimensional arrays. For example:
我使用逗号运算符来打印日志输出。它实际上与
ostream::operator<<
非常相似,但我发现逗号运算符实际上更好更适合该任务。所以我有:
它有这些很好的属性
逗号运算符的优先级最低。因此,如果您想流式传输表达式,即使您忘记了括号,事情也不会混乱。比较:
您甚至可以毫无问题地在内部混合比较运算符,例如
逗号运算符在视觉上很小。将许多东西粘在一起时不会扰乱阅读
它与逗号运算符的含义一致,即“打印这个”,然后“打印那个”。
I use the comma operator for printing log output. It actually is very similar to
ostream::operator<<
but I find the comma operator actually better for the task.So I have:
It has these nice properties
The comma operator has the lowest priority. So if you want to stream an expression, things do not mess up if you forget the parenthesis. Compare:
you can even mix comparisons operators inside without a problem, e.g.
The comma operator is visually small. It does not mess up with reading when gluing many things together
It aligns with the meaning of the comma operator, i.e. "print this" and then "print that".
在 SOCI - C++ 数据库访问库中,它用于实现接口的入站部分
: 基本原理常见问题解答:
In SOCI - The C++ Database Access Library it is used for the implementation of the inbound part of the interface:
From the rationale FAQ:
一种可能性是 Boost Assign 库(尽管我很确定有些人会认为这种滥用而不是很好的用途)。
Boost Spirit 可能也会重载逗号运算符(它几乎重载了其他所有内容......)
One possibility is the Boost Assign library (though I'm pretty sure some people would consider this abuse rather than a good use).
Boost Spirit probably overloads the comma operator as well (it overloads almost everything else...)
实际用途之一是在宏中有效地使用可变参数。顺便说一句,变量参数早期是 GCC 中的扩展,现在是 C++11 标准的一部分。
假设我们有一个
类X
,它将A
类型的对象添加到其中。即如果我们想将 1 个或多个
A
对象添加到X buffer;
中怎么办?例如,
上面的宏,如果用作:
那么它将扩展为:
因此,这将是使用逗号运算符的完美示例,因为变量参数也以相同的方式扩展。
因此,为了解决这个问题,我们重载
comma
运算符并将其包裹在+=
周围,如下所示One of the practical usage is for effectively using it with variable arguments in macro. By the way, variable arguments was earlier an extension in GCC and now a part of C++11 standard.
Suppose we have a
class X
, which adds object of typeA
into it. i.e.What if we want to add 1 or more objects of
A
intoX buffer;
?For example,
Above macro, if used as:
then it will expand to:
Hence, this will be a perfect example of using comma operator, as the variable arguments expand with the same.
So to resolve this we overload
comma
operator and wrap it around+=
as below同样,我收到了一个带有逗号运算符重载的 github pull 请求。 以下操作:
在我的代码中我可以执行
Along the same lines, I was sent a github pull request with comma operator overload. It looked something like following
then in my code I can do:
以下是 OpenCV 文档中的示例(http://docs.opencv.org /modules/core/doc/basic_structs.html#mat)。逗号运算符用于 cv::Mat 初始化:
Here is an example from OpenCV documentation (http://docs.opencv.org/modules/core/doc/basic_structures.html#mat). The comma operator is used for cv::Mat initialization: