В комментариях и ответах на этот вопрос: оптимизация компилятора виртуальных функций c++ утверждается, что вызов виртуальной функции в цикле не может быть девиртуализирован, так как виртуальная функция может заменить this
другим объектом с помощью размещения new, например:
void A::foo() { // virtual
static_assert(sizeof(A) == sizeof(Derived));
new(this) Derived;
}
Пример из статьи блога LLVM о девиртуализации
Теперь мой вопрос: это разрешено стандартом?
Я мог бы найти это на cppreference о повторном использовании хранилища: (акцент мой)
Программа не требует вызова деструктора объекта, чтобы завершить его время жизни, если объект тривиально разрушен или если программа не полагается на побочные эффекты деструктора. Однако, если программа завершает время жизни нетривиального объекта, она должна гарантировать, что новый объект того же типа будет создан на месте (например, через новое место размещения), прежде чем деструктор можно будет назвать неявным
Если новый объект должен иметь один и тот же тип, он должен иметь одинаковые виртуальные функции. Таким образом, невозможно иметь другую виртуальную функцию, и, таким образом, девиртуализация приемлема.
Или я что-то неправильно понимаю?