c ++将使用非类型参数从模板创建函数的多个实例

时间:2019-06-06 02:46:15

标签: c++ templates g++

我最近了解了c ++模板,并正在使用矩阵类对其进行测试:

template<typename T>

class Matrix
{
    public:
        Matrix();

        int width;
        int height;

        Matrix operator*(const Matrix& rMatrix)
        Matrix operaor+(const Matrix& rMatrix)

        // other matrix operations/functions here
    private:
        T* data;
};

然后我发现模板可以采用非类型参数,这使我可以这样做:

template<typename T, int width, int height>

class Matrix
{
    public:
        Matrix();

        template <int width2>
        Matrix<T, width2, height> operator*(const Matrix<width2, width>7 rMatrix)

        // other matrix operations/functions here

    private:
        T* data;
};

我认为,如果您知道编译时所需的所有大小,则后者可能会更好,因为如果矩阵的大小错误(对于乘法/加法运算),它将产生编译错误,而前者迫使我在运行时进行检查。但是,我担心编译器会生成不同的函数,以将4x4添加到4x4,而将3x3添加到3x3(假设两者具有相同的类型),这样效率低下。

所以我的问题是这样的:当非类型参数(在上面的示例中为矩阵宽度/高度)发生变化时,我正在使用的(g ++)编译器会从模板生成多个函数吗?

编辑/说明:

  • 函数不是内联定义的(它们在单独的.tpp文件中)
  • “低效率”,是指(据我所知)在函数上具有这些变化会导致编译后的可执行文件比其他情况要大

1 个答案:

答案 0 :(得分:0)

看看C++ Insights

如果在此处粘贴代码并添加一个main函数,该函数使用两种具有不同高度和宽度的矩阵类型(请参阅here并单击“播放”按钮),则可以观察到编译器生成:

template<typename T, int width, int height>
class Matrix
{
public:
    Matrix();

    template <int width2>
    Matrix<T, width2, height> operator*(const Matrix<T, width2, width> rMatrix);

    // other matrix operations/functions here

private:
    T* data;
};

/* First instantiated from: insights.cpp:18 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class Matrix<double, 1, 2>
{

public: 
  Matrix();

  template<int width2>
  Matrix<double, width2, 2> operator*(const Matrix<double, width2, 1> rMatrix);

private: 
  double * data;
public: 
  // inline constexpr Matrix(const Matrix<double, 1, 2> &) = default;
  // inline constexpr Matrix(Matrix<double, 1, 2> &&) = default;
};

#endif


/* First instantiated from: insights.cpp:19 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class Matrix<double, 2, 1>
{

public: 
  Matrix();

  template<int width2>
  Matrix<double, width2, 1> operator*(const Matrix<double, width2, 2> rMatrix);

private: 
  double * data;
public: 
  // inline constexpr Matrix(const Matrix<double, 2, 1> &) = default;
  // inline constexpr Matrix(Matrix<double, 2, 1> &&) = default;
};

#endif


int main()
{
  Matrix<double, 1, 2> Matrix1 = Matrix<double, 1, 2>();
  Matrix<double, 2, 1> Matrix2 = Matrix<double, 2, 1>();
}

因此,是的,生成了代码中其他地方使用的所有宽度和高度组合的版本。