#опытным
Виртуальные функции являются средством реализации динамического полиморфизма в С++. Почему он вообще называется динамическим?
Да потому что выбор конкретной реализации происходит в рантайме, а не во время компиляции.
Но что, если я вам скажу, что мы можем реализовывать полиморфизм времени компиляции с помощью виртуальных функций?
Выглядит как оксюморон, но подождите кидаться грязными тряпками. Сейчас все разберем.
Начиная с С++11 у нас есть constexpr функции. Эти функции могут быть вычислены на этапе компиляции, если их аргументы также известны на этом этапе. Аргументы могут быть константами, литералами, constexpr переменными или результатом вычисления других constexpr функций.
constexpr int double_me(int n)
{
return n * 2;
}
// условие верное и мы не падаем
static_assert(double_me(4) == 8);
// условие ложно и компиляция прервется на этой строчке
static_assert(double_me(4) == 7);
В примере мы определяем constexpr функцию double_me и проверяем с помощью static_assert'а то, что она вычисляется во время компиляции.
Изначально constexpr функции были довольно ограничены по возможностям своего применения. Однако с новыми стандартами спектр применений расширяется, так как все больше операций из стандартной библиотеки можно проводить в compile-time. Сейчас даже с контейнерами в complie-time можно работать. Но мы сейчас не об этом.
Начиная с С++20 constexpr функции могут быть виртуальными!
struct VeryComplicatedCaclulation
{
constexpr virtual int double_me(int n) const = 0;
};
struct Impl: VeryComplicatedCaclulation
{
constexpr virtual int double_me(int n) const override
{
return 2 * n;
}
};
constexpr auto impl = Impl{};
// для полиморфизма с виртуальными функциями нужна ссылка
constexpr const VeryComplicatedCaclulation& impl_ref = impl;
constexpr auto a = impl_ref.double_me(4);
static_assert(a == 8); // true
Все как мы привыкли: делаем иерархию классов с виртуальной функцией, только везде на всех этапах приписываем constexpr. И это работает!
А где это может быть использовано, посмотрим в следующий раз.
Increase your usability. Stay cool.
#cpp11 #cpp20 #cppcore