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

Why is overriding both the global new operator and the class-specific operator not ambiguous behaviour?

考虑以下代码:

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;

但是这个带有 new 运算符的编译器编译得很好,并且会调用 class-specific 的那个。

Foo* a = new Foo();

为什么没有出现编译错误?编译器是否以不同方式对待 new 运算符? (对标准的任何引用将不胜感激。)

您的全局 new 运算符与 class Foo 没有直接关系。 class 特定 new 优先于全局 new。没有歧义。

您的 operator+ 确实与 class Foo 具体相关。在 class 外部定义的运算符和定义在 class 内部的运算符之间没有优先级。因此你会产生歧义。

Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)

关于全局 new 和 class 特定 new 之间的优先级,参考文献说 this:

As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.

所以 class 具体 new 具有优先权。

关于 + 的重载,您可以让成员重载 全局重载(通常作为 [=26 的 friend =]) 但不是两者都是因为它产生的歧义。

如果定义了 class' operator new,则始终是首选:

[expr.new]/9

If the new-expression begins with a unary ​::​ operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.

阅读起来可能很棘手:如果 new-expression 不是以 :: 开头并且 分配的类型 是 class 类型,然后 new 在 class' 范围内查找。