В чем преимущество виртуальных функций constexpr в C ++ 20?
Я легко могу сказать, что, объявляя функцию как, мы оцениваем ее во время компиляции, и это экономит время во время выполнения, поскольку результат уже был получен.
С другой стороны, виртуальные функции должны быть разрешены во время выполнения. Следовательно, я полагаю, что мы не можем избавиться от процесса урегулирования. Только результат можно получить быстро благодаря механизму
constexpr
функции.
Есть ли другие преимущества
constexpr virtual
функции?
1 ответ
Очевидным преимуществом является то, что теперь вы даже можете выполнять вызовы виртуальных функций во время компиляции.
struct Base {
constexpr virtual int get() { return 1; }
virtual ~Base() = default;
};
struct Child : Base {
constexpr int get() override { return 2; }
};
constexpr int foo(bool b) {
Base* ptr = b ? new Base() : new Child();
auto res = ptr->get(); // this call is not possible prior to C++20
delete ptr;
return res;
}
constexpr auto BaseVal = foo(true);
constexpr auto ChildVal = foo(false);
Вы не можете использовать
Теперь думаем о том, какую пользу мы могли бы получить от вызовов виртуальных функций во время компиляции: может быть, во время компиляции. C++ имеет в основном два механизма для работы с полиморфизмом:
- шаблоны и
- виртуальные функции.
Оба решают по существу одни и те же проблемы, но на разных этапах жизненного цикла вашей программы. Конечно, приятно выполнять как можно больше вычислений во время компиляции и, следовательно, иметь наилучшую производительность во время выполнения. Однако это не всегда осуществимый подход, поскольку время компиляции может быстро возрасти из-за того, как работают шаблоны.
Спекуляции начинаются здесь. А что, если мы расширим этапы, на которых можно вызывать виртуальные функции, а также разрешим их вызывать во время компиляции? Это позволило бы нам в некоторых случаях заменить сильно рекурсивные или вложенные шаблоны вызовами виртуальных функций. Если предположить, что интерпретатор constexpr работает быстрее, чем компилятор, рекурсивно разрешающий шаблоны, вы можете увидеть некоторое сокращение времени компиляции.
Конечно, это преимущество затмевается повышением производительности, которое вы получите от концепций и модулей.
Еще одно преимущество заключается в природе constexpr в целом: UB запрещен во время постоянного вычисления. Это означает, что вы можете проверить, свободны ли ваши виртуальные функции от UB, с помощью нескольких статических утверждений.