使用模板 <int size> 比动态分配有什么好处?

What the benefits by using the template<int size> than dynamic allocate?

我正在阅读 pbrt,它定义了一个类型:

template <int nSpectrumSamples>
class CoefficientSpectrum;
class RGBSpectrum : public CoefficientSpectrum<3> {
    using CoefficientSpectrum<3>::c;
typedef RGBSpectrum Spectrum;
// typedef SampledSpectrum Spectrum;

而作者说:

"We have not written the system such that the selection of which Spectrum implementation to use could be resolved at run time; to switch to a different representation, the entire system must be recompiled. One advantage to this design is that many of the various Spectrum methods can be implemented as short functions that can be inlined by the compiler, rather than being left as stand-alone functions that have to be invoked through the relatively slow virtual method call mechanism. Inlining frequently used short functions like these can give a substantial improvement in performance."

1.Why 模板可以内联函数但正常方式不能?

2.Why难道正常的方法一定要用虚方法吗?

链接到整个头文件: https://github.com/mmp/pbrt-v3/blob/master/src/core/spectrum.h

要内联函数调用,编译器必须知道 1. 调用了哪个函数以及 2. 该函数的确切代码。 virtual 函数的全部目的是将调用哪个函数的选择推迟到 运行 时间,因此编译器只能通过需要非常特定情况的复杂优化技术才能获得上述信息1.

模板和虚函数(即多态)都是编码抽象的工具。使用 CoefficientSpectrum 的代码并不真正关心频谱的实现细节,只是你可以,例如将它与 RGB 相互转换——这就是它使用抽象的原因(以避免为每种光谱重复代码)。正如您引用的评论中所解释的那样,在这里使用多态进行抽象意味着编译器很难优化代码,因为它从根本上将实现的选择推迟到 运行 时间(这有时有用但不是绝对必要的)这里)。通过要求在编译时选择实现,编译器可以轻松优化(即内联)代码。

1例如,一些编译器能够优化掉 std::function 抽象,它通常使用多态来进行类型擦除。当然,这只有在所有必要信息都可用的情况下才能起作用。