我可以很容易地说,通过将函数声明为constexpr
,我们在编译时对其进行评估,这样可以在运行时节省时间,因为结果已经生成。
另一方面,虚函数需要在运行时解析。因此,我想我们无法摆脱解决过程。由于函数的机制,只有结果可以快速获取constexpr
。
constexpr virtual
函数还有其他好处吗?
我可以很容易地说,通过将函数声明为constexpr
,我们在编译时对其进行评估,这样可以在运行时节省时间,因为结果已经生成。
另一方面,虚函数需要在运行时解析。因此,我想我们无法摆脱解决过程。由于函数的机制,只有结果可以快速获取constexpr
。
constexpr virtual
函数还有其他好处吗?
那么明显的好处是你现在甚至可以在编译时进行虚函数调用。
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);
get
在 C++20 之前,您不能通过常量表达式中的基指针使用该函数。如果你做到了constexpr
,你可以。例子。
现在考虑在编译时我们可以从虚函数调用中获得什么好处:也许是编译时间。C++ 基本上有两种机制来处理多态性:
两者都解决了基本相同的问题,但在程序生命周期的不同阶段。当然,在编译时进行尽可能多的计算是很好的,因此在运行时具有最佳性能。但是,这并不总是一种可行的方法,因为模板的工作方式会导致编译时间迅速增加。
猜测从这里开始。现在,如果我们扩大可以调用虚函数的阶段并允许在编译时调用它们呢?在某些情况下,这将允许我们用虚函数调用替换大量递归或嵌套的模板。假设 constexpr 解释器比编译器递归解析模板更快,您可以看到一些编译时间减少。
当然,这种好处被您从概念和模块中获得的性能提升所掩盖。
另一个好处通常在于 constexpr 的性质:在持续评估期间禁止 UB。这意味着您可以通过一些静态断言检查您的虚拟功能是否是 UB 免费的。