运算符重载(尤其是“新”)数量如何工作?
我从来没有完全理解运算符重载的参数列表是如何以系统的方式确定的,并且我现在对我现在遇到的问题感到特别困惑。
当您重载一元运算符时,它有一个参数,如果它是类成员,则为零。当您重载二元运算符时,它有两个参数,如果它是类成员,则有一个参数。至少看起来是这样的。但是,我遇到了 operator new
(不是类成员)的问题。
在我正在工作的代码库中,就像我过去见过的其他地方一样(例如这里 例如)有一个类似 #define new new(__FILE__, __LINE__)
的定义以及带有签名 void *new(size_t size, const char *file, unsigned line)
或类似的东西用于内存调试。我注意到我的项目中的项目实际上与之前链接的项目不同。这对我来说是一个问题,因为由于某种原因它弄乱了新的展示位置。我看过《C++ 编程语言》,如果它解释了这一点,我就错过了。
new
在这方面是否有特殊之处,即它是否具有特定语言定义的额外调试签名?看起来并非如此,因为正如我上面提到的,我在不同的地方看到了略有不同的签名。如果有的话,还有哪些其他运营商有不明显的签名,它们是什么?这些不同的签名是不是一些特定于实现的附加功能?如果是这样,对于大多数实现的作用是否有任何一般规则?或者,这是否像我在标题中暗示的那样是一个数量问题?您可以在签名中添加任意数量的额外参数吗?如果您使用 new 关键字本身和您想要的新类型之间的参数调用 new,您可以做任何事情吗?还是我更困惑,还有什么我想念的?
最重要的是,从短期来看(尽管我真的很想了解这一点),到底发生了什么事情让我的展示位置new
变得混乱?该宏导致类似 new ("file.cpp", 100) (class_pointer) class_t
的扩展。问题可能是括号中的两组,还是其他什么?
I've never quite understood how the argument lists for operator overloading are determined in a systematic way, and I'm particularly confused by a problem I have now.
When you overload a unary operator it has one argument, or zero if it's a class member. When you overload a binary operator it has two arguments, or one if it's a class member. At least that's the way it would seem to work. I'm having a problem with operator new
(not a class member) however.
In a codebase I'm working in, as in other places I have seen in the past (like here for example) there is a define like #define new new(__FILE__, __LINE__)
and a corresponding function with the signature void *new(size_t size, const char *file, unsigned line)
or something like it for memory debugging. I note that the one in my project is actually different from the previously linked one. This presents a problem for me, because for some reason it's messing up a placement new. I've looked in The C++ Programming Language, and if it explains this I'm missing it.
Is new
special in this regard, i.e. does it have specific language defined extra debug signatures? It doesn't seem like it because, as I noted above, I've seen slightly different signatures in different places. If it does, what other operators have non-obvious signatures, and what are they? Are these varied signatures instead some implementation specific extras? If so, are there any general rules as to what most implementations do? Alternatively, is it an arity issue like I implied in my title? Can you just tack on as many extra arguments as you want in the signature and if you call new with the arguments between the new
keyword itself and the new type you want you can just do whatever? Or am I even more confused, and there's something else I'm missing?
Most importantly in the short term (although I'd really like to understand this), what's going on the messes up my placement new
? The macro is causing an expansion something like new ("file.cpp", 100) (class_pointer) class_t
. Is the problem the two groups in parenthesis maybe, or something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
operator new 更接近函数,因为您可以提供任意数量的重载,编译器将根据函数重载规则选择版本。
因此,当您执行 new ((T1)value1, (T2)value2) TYPE 时,它将被路由到:
您的宏的问题在于它假设您正在调用 new 的普通版本并且它可以使用预处理器将其转换为对调试 new 的调用。当您需要调用不同版本的 new 时,该宏就会被破坏。
如果您需要调用新的放置(或任何其他特殊的新),您可以通过关闭该宏来解决您的问题:
operator new is closer to functions in that you can provide as many overloads as you want and the compiler will choose the version based on function overload rules.
So, when you do
new ((T1)value1, (T2)value2) TYPE
, that will get routed to:The problem with your macro is that it is assuming you are calling the plain version of new and that it can use the preprocessor to turn that into a call to debugging new. The macro is broken when you need to call a different version of new.
If you need to call placement new (or any other special new), you can fix your issue by turning off that macro:
重载运算符的数量是您声明的任何内容。对于以符号 (+) 命名的运算符,如果将它们定义为具有额外的参数,则它们只能通过显式调用来调用。 (运算符+(a,b,c,d,e))。对于operator new,你必须至少给它一个arg,但是你可以给它任意多个arg。常规运算符重载决定调用哪一个运算符。
The arity of an overloaded operator is whatever you declare. For the operators named after symbols (+), if you define them to have extra args, they will only be invoked via an explicit call. (operator +(a, b, c, d, e)). For operator new, you must give it at least one arg, but you may give it as many as you want. Regular operator overloading determines which one gets called.