0

I am trying to create a custom 'Matrix' class in C++ and have run into an "Undefined symbols for architecture x86_64:" error that I cannot understand. My relevant code is-

HEADER

#ifndef CORE_H
#define CORE_H
#include <stdint.h>

class Size
{
public:
    Size(const uint64_t nrows, const uint64_t ncols, const uint64_t nframes);

    uint64_t rows;
    uint64_t cols;
    uint64_t frames;
};

template <typename T>
class Matrix
{
public:
    Matrix(const uint64_t rows, const uint64_t cols, const uint64_t frames);
    Matrix(const uint64_t rows, const uint64_t cols, const uint64_t frames, T *data);

    void print();

private:
    Size sz;
    T *_data;
};

#endif //CORE_H

SOURCE

#include <string.h>
#include <cstdlib>
#include <stdio.h>

#include "core.h"

Size::Size(const uint64_t nrows, const uint64_t ncols, const uint64_t nframes)
{
    rows = nrows;
    cols = ncols;
    frames = nframes;
}

template <typename T>
Matrix<T>::Matrix(const uint64_t rows, const uint64_t cols, const uint64_t frames)
{
    Matrix<T>(rows, cols, frames, malloc(rows * cols * frames * sizeof(T)));
}

template <typename T>
Matrix<T>::Matrix(const uint64_t rows, const uint64_t cols, const uint64_t frames, T *data)
{
    sz = Size(rows, cols, frames);
    _data = data;
}

template <typename T>
void Matrix<T>::print()
{
    printf("[");
    for (uint64_t f = 0; f < sz.frames; f++) {
        printf("[");
        for (uint64_t r = 0; r < sz.rows; r++) {
            for (uint64_t c = 0; c < sz.cols; c++) {
                printf("%.3f,", element(r, c, f));
            }
            printf("\n");
        }
        printf("]\n");
    }
    printf("]\n");
}

TEST

#include "core.h"

int main(int argc, char *argv[])
{
    int data[] = { 1, 2, 3, 4, 5, 6, 7, 8};
    Matrix<int> mat(2, 2, 2, data);
    mat.print();
    return 0;
}

ERROR

Undefined symbols for architecture x86_64:
  "Matrix<int>::print()", referenced from:
      _main in rand.cpp.o
  "Matrix<int>::Matrix(int, int, int, int*)", referenced from:
      _main in rand.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [examples/rand] Error 1
make[1]: *** [examples/CMakeFiles/rand.dir/all] Error 2
make: *** [all] Error 2

I'm sure it is something small but I can't figure it out. Any help would be really appreciated!

user2465166
  • 5
  • 1
  • 3
  • Have you added the source file to your project? Including `"core.h"` allows the compiler to understand these symbols, adding "core.cpp" allows the linker to link them (after the compiler has compiled them into object code). – barak manos Sep 17 '14 at 06:46
  • possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – user657267 Sep 17 '14 at 07:01

1 Answers1

1

Template functions (including member functions of template classes) need to be implemented in a header file so their definitions (not just declarations) are visible in all translation units where they might be used. See this SO question for more information.

Move the definitions of your constructor and print functions into your header file, below the definition of the Matrix class template.

Wyzard
  • 33,849
  • 3
  • 67
  • 87
  • I fixed it by adding template class Matrix definitions to the bottom of my .cpp file as per the linked question. Thanks! – user2465166 Sep 17 '14 at 15:34