Как возможна виртуальная функция constexpr? - PullRequest
2 голосов
/ 03 мая 2019

Начиная с C ++ 2a, виртуальные функции теперь могут быть constexpr.Но, насколько я знаю, вы все еще не можете вызывать произвольные указатели на функции в контексте constexpr.

Динамический полиморфизм обычно реализуется с использованием vtable, который содержит указатель на функцию для вызова.

Кроме того, динамическийполиморфизм с virtual полезен для вызова переопределяющих функций типа, который вы не знаете, какой это во время компиляции.Например:

struct A {
    virtual void fn() const {
        std::cout << 'A' << std::endl;
    }
};

void a_or_b(A const& a) {
    // The compiler has no idea `B` exists
    // it must be deferred at runtime
    a.fn();
}

struct B : A {
    void fn() const override {
        std::cout << 'A' << std::endl;
    }
};

int main() {
    // We choose which class is sent
    a_or_b(rand() % 2 ? A{} : B{});
}

Таким образом, учитывая те, что указатели функций не могут быть вызваны во время компиляции, и виртуальный полиморфизм используется, когда у компилятора недостаточно информации для статического определения, какую функцию вызывать, как виртуальный constexprфункции возможны?

1 Ответ

10 голосов
/ 03 мая 2019

Имейте в виду, что constexpr виртуальные функции будут вызываться во время компиляции только тогда, когда тип уже известен компилятору и, очевидно, они не будут вызываться через виртуальную диспетчеризацию.

СоответствующиеПредложение дает аналогичное объяснение:

Виртуальные вызовы функций в настоящее время запрещены в константных выражениях.Поскольку в константном выражении требуется знать динамический тип объекта (например, для диагностики неопределенного поведения в приведениях), ограничение является ненужным и искусственным.Мы предлагаем снять ограничение.

У него также есть очень хороший мотивирующий пример.

...