了解模板代码膨胀

Understanding template code bloat

本文关键字:膨胀 代码 了解      更新时间:2023-10-16

我正在阅读Scott Meyers C++,并发现了所谓的代码膨胀的概念。他提供了一个如何通过继承来减少它的例子:

template <typename T>
class SquareMatrixBase{
protected:
    void invert(std::size_t matrixSize);    // <------------ HERE
}
template <typename T, std::size_t n>
class SquareMatrix : private SquareMatrixBase<T>{
private:
    using SquareMatrix<T>::invert;
public:
    void invert(){ invert(n) }
}

现在,在项目摘要中,他指出

模板生成多个类和多个函数,因此不依赖于模板参数的模板代码会导致膨胀。

因此,在这个例子中,我们有SquareMatrixBase<T>::invert(std::size_t),它不依赖于模板参数。因此,它会导致代码膨胀。这不是我们试图消除的东西吗?我错过了什么?

因此,在这个例子中,我们有SquareMatrixBase<T>::invert(std::size_t),它不依赖于模板参数。因此,它会导致代码膨胀。这不是我们试图消除的东西吗?我错过了什么?

没有。您忽略了invert对矩阵执行的操作将依赖于T,因此为每个T实例化一个invert是合适的。

对于类型T和矩阵大小n的每个组合都有一个实例化是不可取的,这就是为什么基于这两个参数模板化的派生SquareMatrix类服从基类的实现。它实际上只是将矩阵大小常量作为运行时值注入。

由于SquareMatrix模板是在Tn这两个对象上参数化的,因此即使您可能具有相同的类型T,如果您具有不同的n,并且invertSquareMatrix的成员函数,它也会导致函数的多个版本(这个数字取决于我们实例化的具有相同T但不同大小的SquareMatrix的数量)。

Scott正在演示我们如何通过简单地继承仅在T上参数化的类型来避免由这些多个副本引起的潜在膨胀,因此无论n的值如何,都可以共享invert的实现。

他在运行时将size值传递给基类函数,因此所有相同的信息都可用于该函数。