请考虑以下代码:
class Foo
{
public:
//class-specific
Foo operator+(Foo& rhs)
{
return Foo(); //Just return a temporary
}
void* operator new(size_t sd)
{
return malloc(sd);
}
};
//global
Foo operator+(Foo& lhs, Foo& rhs)
{
return Foo();
}
void* operator new(size_t sd)
{
return malloc(sd);
}
此代码不会编译,说明调用不明确,因为它匹配两个运算符:
Foo a, b;
a + b;
但是这个带有新运算符的运算符编译得很好,并且会调用特定于类的运算符。
Foo* a = new Foo();
为什么不会导致编译错误?编译器是否以不同的方式对待新运算符?(任何对该标准的引用将不胜感激。
为什么不会导致编译错误?编译器是否以不同的方式对待新运算符?(任何对该标准的引用将不胜感激(
关于全局new
和类特定new
之间的优先级,参考文献是这样说的:
如分配函数中所述,C++程序可以为这些功能提供全局和特定于类的替换。如果 new-expression 以可选的 :: 运算符开头,如 ::new T 或 ::new T[n],则将忽略特定于类的替换(在全局范围内查找该函数(。否则,如果 T 是类类型,则查找将从 T 的类范围开始。
因此,特定于类new
具有优先级。
关于+
的重载,你可以让成员重载或全局重载(通常作为类的friend
(,但不能两者兼而有之,因为它会产生歧义。
如果定义了类operator new
,则始终首选:
[expr.new]/9
如果new-表达式以一元运算符开头
::
,则会在全局范围内查找分配函数的名称。否则,如果分配的类型是类类型T
或其数组,则分配函数的名称将在T
的范围内查找。如果此查找无法找到名称,或者分配的类型不是类类型,则会在全局范围内查找分配函数的名称。
阅读起来可能很棘手:如果new-expression不以::
开头,并且分配的类型是类类型,则在类的范围内查找new
。
您的全局new
运算符与类Foo
没有直接关系。特定于类new
优先于全局new
。没有歧义。
您的operator+
确实与类Foo
特别相关。在类外部定义的运算符和在类内部定义的运算符之间没有优先级。因此,你会得到歧义。