为什么覆盖全局新运算符和类特定运算符不是模糊行为?

A. *_* S. 10 c++ new-operator language-lawyer c++11 c++14

请考虑以下代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

此代码将无法编译,说明调用不明确,因为它匹配两个运算符:

Foo a, b;
a + b;
Run Code Online (Sandbox Code Playgroud)

但是这个带有new运算符的编译器很好,并且会调用特定于类的运算符.

Foo* a = new Foo();
Run Code Online (Sandbox Code Playgroud)

为什么不导致编译错误?编译器是否以不同方式处理新运算符?(任何对标准的引用都将不胜感激.)

P.W*_*P.W 7

为什么不导致编译错误?编译器是否以不同方式处理新运算符?(任何对标准的引用将不胜感激)

对于全球的优先级new和类特定的new,参考说这个:

如分配函数中所述,C++程序可以为这些函数提供全局和类特定的替换.如果new-expression以可选::运算符开头,如:: new T或:: new T [n],则将忽略特定于类的替换(在全局范围内查找该函数).否则,如果T是类类型,则查找从T的类范围开始.

所以特定类new具有优先权.

关于重载+,你可以有成员重载全局重载(通常作为friend类的一个),但不能同时因为它产生的歧义.


YSC*_*YSC 5

operator new如果定义,则始终首选“类” :

[expr.new]/9

如果new表达式以一元开头?::?运算符,分配函数的名称在全局范围内查找。否则,如果分配的类型是类类型T或其数组,则在的范围内查找分配函数的名称T。如果此查找找不到名称,或者分配的类型不是类类型,则在全局范围内查找分配函数的名称。

读取起来可能很棘手:如果new-expression不是以开头,::并且分配的类型是类类型,则new在类的范围内进行查找。