0

Possible Duplicate:
Why can templates only be implemented in the header file?

I'm working on a Matrix class, and I have a method SetMatrix that I use to initialize the array with standard c++ two dimensional arrays.

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];
}

and the method works well, but when I try to move it from the header file to the .cpp implementation file, I get a linker error.

Matrix.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++ output:

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

I was wondering how to move it to the .cpp file, or if I'm just out of luck, or if there's a more elegant way to do it? Most of the resources I've found were dealing with static method of template classes, not a static template method of a non-template class. Here's my calling code, too, if it will help

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

    Matrix matrix(2, 3);

    Matrix::SetMatrix<2, 3>(matrix, input);
    matrix.Print();
}
Community
  • 1
  • 1
BrandonToner
  • 111
  • 1
  • 1
  • 3
  • Have a look at http://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file – Ignitor Jan 25 '13 at 17:45

1 Answers1

0

main.cpp cannot see the definition of the SetMatrix member function template, so it cannot instantiate it when this is being called. The compiler can only rely on the fact that the code for that function has been or will be produced while processing some other translation unit (i.e. some other .cpp file).

However, the mere presence of the definition of the SetMatrix function in matrix.cpp does not mean that the function template gets instantiated there (in fact, it does not, because no line of code in that file invokes SetMatrix); consequently, the object code for that function will not be produced.

So eventually the code for the instantiated function template is not present in any translation unit, and a linker error is raised.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451