0

我可以很容易地说,通过将函数声明为constexpr,我们在编译时对其进行评估,这样可以在运行时节省时间,因为结果已经生成。

另一方面,虚函数需要在运行时解析。因此,我想我们无法摆脱解决过程。由于函数的机​​制,只有结果可以快速获取constexpr

constexpr virtual函数还有其他好处吗?

4

1 回答 1

3

那么明显的好处是你现在甚至可以在编译时进行虚函数调用。

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 免费的。

于 2021-12-21T14:09:11.600 回答