现在是否可以生成非内联的 C++ 模板函数?

Is it possible to generate C++ template functions that are not inline these days?

过去,模板函数并不总是内联的。在 .cpp 文件中定义模板函数存在巨大的问题,因为它不知道不同的模块作为模板参数传入了什么。所以模板几乎都是纯头文件,包含所有内容。

但是,代码可能会非常大,所以如果我想创建一个模板 class,例如 Matrix 并将方法实际生成为函数,有什么办法可以做到吗?

这曾经有效:

template<typename Precision>
Matrix<Precision> operator *(const Matrix<Precision>& a, const Matrix<Precision>& b) {

}

然后确保为所需类型生成了所有方法:

Matrix<float>;
Matrix<double>;
Matrix<long double>;
Matrix<int>;

g++ 现在给出类型规范的错误(什么都不做) 并且该函数是作为内联生成的,因此不可调用。

在 C++20 中有什么方法可以做到这一点吗?模块能解决这个问题吗?

问题与运算符是否为 inline 正交,模板的定义 (body) 必须在实例化时可用。

您已经明确实例化了 Matrix class,但问题是您的 operator * 是一个自由运算符,因此它独立于 Matrix 并且需要单独实例化。

.h 文件:

// template declaration
template <typename Precision>
Matrix<Precision> operator*(Matrix<Precision> const& a, Matrix<Precision> const& b);

// explicit instantiation declaration
extern template Matrix<float> operator*(Matrix<float> const&, Matrix<float> const&);
extern template Matrix<double> operator*(Matrix<double> const&, Matrix<double> const&);

.cpp 文件:

// template definition
template <typename Precision>
Matrix<Precision> operator*(Matrix<Precision> const& a, Matrix<Precision> const& b) {
  // . . .
}

// explicit instantiation
template Matrix<float> operator*(Matrix<float> const&, Matrix<float> const&);
template Matrix<double> operator*(Matrix<double> const&, Matrix<double> const&);

所有这一切的缺点是这里没有任何内容会被内联(除非您使用 LTO),这会损害 run-time 性能。因此很少使用显式模板实例化。

模块不能解决这个问题,但它们可以通过仅解析 headers 一次并以二进制形式存储中间表示来加快常规构建时间。