0

可能重复:
为什么模板只能在头文件中实现?

我正在研究一个 Matrix 类,并且我有一个方法 SetMatrix 用于使用标准 c++ 二维数组初始化数组。

template <int width, int height>
static void SetMatrix(Matrix& matrix, double array[][width]) {
    if (matrix.height_ != height || matrix.width_ != width) {
        fprintf(stderr, "Incorrect matrix size\n");
        return;
    }
    for (int y = 0; y < height; ++y)
        for (int x = 0; x < width; ++x)
            matrix.matrix_[y][x] = array[y][x];
}

并且该方法运行良好,但是当我尝试将其从头文件移动到 .cpp 实现文件时,出现链接器错误。

矩阵.cpp:

template <int width, int height>
void Matrix::SetMatrix(Matrix& matrix, double array[][width]) {
    if (matrix.height_ != height || matrix.width_ != width) {
        fprintf(stderr, "Incorrect matrix size\n");
        return;
    }
    for (int y = 0; y < height; ++y)
        for (int x = 0; x < width; ++x)
            matrix.matrix_[y][x] = array[y][x];
}

g++ 输出:

g++ -Wall -Wextra main.cpp Matrix.cpp -o matrix
/tmp/ccMkObBs.o: In function `main':
main.cpp:(.text+0x81): undefined reference to `void Matrix::SetMatrix<2, 3>(Matrix&, double (*) [2])'
collect2: error: ld returned 1 exit status

我想知道如何将它移动到 .cpp 文件,或者我只是运气不好,或者是否有更优雅的方式来做到这一点?我发现的大多数资源都是处理模板类的静态方法,而不是非模板类的静态模板方法。如果有帮助,这也是我的调用代码

int main() {
    double input[3][2] = {
        {1, 2},
        {3, 4},
        {5, 6}
    };

    Matrix matrix(2, 3);

    Matrix::SetMatrix<2, 3>(matrix, input);
    matrix.Print();
}
4

1 回答 1

0

main.cpp看不到SetMatrix成员函数模板的定义,因此在调用 this 时无法实例化它。.cpp编译器只能依赖于在处理其他翻译单元(即其他文件)时已经或将要生成该函数的代码这一事实。

但是,仅仅存在SetMatrixin 函数的定义matrix.cpp并不意味着函数模板在此处被实例化(事实上,它没有,因为该文件中没有任何代码行调用SetMatrix);因此,不会生成该函数的目标代码。

因此,最终实例化函数模板的代码不会出现在任何翻译单元中,并且会引发链接器错误。

于 2013-01-25T17:51:33.783 回答