Разрушение на месте по типу с перегруженным оператором-> - PullRequest
2 голосов
/ 09 августа 2011

Предположим, что какой-то тип Foo имеет перегруженный operator->, который возвращает Bar*:

struct Foo
{
    Bar* operator->();
};

Если я хочу уничтожить возвращенный экземпляр Bar на месте из Foo класс, я могу написать следующее?

this->~Bar();

g ++ не нравится этот код.Это работает, если я напишу это:

(*this)->~Bar();

Не применимо ли в этом случае "правило рекурсивной пересылки"?Почему нет?

Ответы [ 3 ]

3 голосов
/ 09 августа 2011

this - указатель на объект типа Foo. Вы переписали оператор -> для объекта, а не указателя.

this->~Bar()

пытается вызвать метод ~ Bar () в Foo.

(*this)->~Bar()

работает, потому что вы вызываете оператор -> объекта.

3 голосов
/ 09 августа 2011

Вот правило для цепочки ->, найденное в 13.5.6 [over.ref] стандарта:

Выражение x->m интерпретируется как (x.operator->())->m для объекта класса x типа T, если существует T::operator->(), и если механизм выбора разрешения перегрузки (13.3) выбран в качестве оператора наилучшего соответствия.

Поскольку this является указателем, а необъект класса, он не применяется.

Вместо этого применимо это правило в 5.2.5 ([expr.ref]):

Для второй опции (стрелка) перваявыражение должно иметь указатель на полный тип класса.Выражение E1->E2 преобразуется в эквивалентную форму (*(E1)).E2;оставшаяся часть 5.2.5 будет касаться только первой опции (точка).

3 голосов
/ 09 августа 2011

Поскольку this является указателем, а не ссылкой, а -> для указателя не имеет возвращаемого значения для пересылки. Рассмотрим эквивалентно

shared_ptr<std::string>* ptr = // some init
ptr->push_back('0'); // error
...