为什么同时覆盖全局新运算符和特定于类的运算符不是模棱两可的行为?



请考虑以下代码:

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特别相关。在类外部定义的运算符和在类内部定义的运算符之间没有优先级。因此,你会得到歧义。

相关内容

最新更新