Почему переопределение как глобального нового оператора, так и оператора, специфичного для класса, не является неоднозначным поведением? - PullRequest
0 голосов
/ 28 сентября 2018

Рассмотрим следующий код:

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();

Почему это не приводит к ошибке компиляции?Компилятор обрабатывает новый оператор по-другому?(Любая ссылка на стандарт будет принята.)

Ответы [ 3 ]

0 голосов
/ 28 сентября 2018

Почему это не приводит к ошибке компиляции?Компилятор обрабатывает новый оператор по-другому?(Любая ссылка на стандарт приветствуется)

Что касается приоритета между глобальным new и специфичным для класса new, в ссылке говорится: this :

Как описано в функции выделения, программа C ++ может предоставлять глобальные и специфичные для класса замены для этих функций.Если выражение new начинается с необязательного оператора ::, как в :: new T или :: new T [n], специфичные для класса замены игнорируются (функция ищется в глобальной области видимости). В противном случае, если T является типом класса, поиск начинается в области видимости класса T.

Таким образом, класс new имеет приоритет.

Относительноперегрузка +, вы можете иметь либо перегрузку члена , либо глобальную перегрузку (обычно как friend класса), но не оба из-за неоднозначности, которую он производит.

0 голосов
/ 28 сентября 2018

Класс 'operator new всегда предпочтителен, если он определен:

[expr.new]/9

Если новое выражение начинается с унарного оператора ::, имя функции распределения ищется в глобальной области видимости.В противном случае, если выделенный тип является типом класса T или его массивом, имя функции распределения ищется в области действия T.Если при этом поиске не удается найти имя или если выделенный тип не является типом класса, имя функции распределения ищется в глобальной области видимости.

Может быть сложно прочитать: если new-expression не начинается с ::, а выделенный тип является типом класса, затем new ищется в области видимости класса.

0 голосов
/ 28 сентября 2018

Ваш глобальный оператор new не имеет прямого отношения к классу Foo.Специфический класс new имеет приоритет над глобальным new.Здесь нет двусмысленности.

Ваш operator+ действительно относится к классу Foo.Не существует приоритета между оператором, определенным снаружи, и оператором, определенным внутри класса.Таким образом, вы получаете двусмысленность.

...