0

I created a sample minimal directory structure with which I am able to re-create my linker error problem. Below is the directory structure I am having:

satyam@sat:~/cpp/build$ ls -R
.:
src  template

./src:
main.cxx  main.o

./template:
tmp.cxx  tmp.hxx  tmp.o

Content of each of the file is as below:

tmp.hxx

template <typename T>
class Array {
private:
    T *ptr;
    int size;
public:
    Array(T arr[], int s);
    void print();
};

tmp.cxx

#include <iostream>
#include "tmp.hxx"

using namespace std;


template <typename T>
Array<T>::Array(T arr[], int s) {
        ptr = new T[s];
        size = s;
        for(int i = 0; i < size; i++)
                ptr[i] = arr[i];
}

template <typename T>
void Array<T>::print() {
        for (int i = 0; i < size; i++)
                cout<<" "<<*(ptr + i);
        cout<<endl;
}

main.cxx

#include <tmp.hxx>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    Array<int> a(arr, 5);
    a.print();
    return 0;
}

First I moved to template directory and made object file of tmp.cxx with below command:

satyam@sat:~/cpp/build/template$ g++ -c tmp.cxx

Then I moved to src directory and made object file of main.cxx with below command:

satyam@sat:~/cpp/build/src$ g++ -c -I ../template/ main.cxx

Finally I tried to make binary in /cpp/build directory with below command and got this linker error:

satyam@sat:~/cpp/build$ g++ -o prog template/tmp.o src/main.o
src/main.o: In function `main':
main.cxx:(.text+0x4e): undefined reference to `Array<int>::Array(int*, int)'
main.cxx:(.text+0x5a): undefined reference to `Array<int>::print()'
collect2: error: ld returned 1 exit status

I tried looking on other threads of SO and found that including tmp.cxx file in main.cxx will resolve the problem, but I really don't want to go with that option as it doesn't looks right. Not sure where to look further.

Any help regarding this would be great.

mSatyam
  • 531
  • 7
  • 25
  • 2
    The linked question provides some alternatives. But your objection that it "doesn't look right" isn't very strong - look at all the header-only libraries that exist for C++ (including much of the standard library itself); they provide implementations in headers. – Mat Nov 04 '19 at 17:44
  • Actually few components in our project seems to work with just inclusion of this type header, i am wondering its working in some places, maybe something special done their. – mSatyam Nov 04 '19 at 17:52
  • 2
    Move all template methods from tmp.cxx to tmp.hxx – Sergey Aleksandrovich Nov 04 '19 at 17:56
  • Sorry my bad just found out that they have indeed included .cxx in other components, so my assumption was wrong that it "doesn't look right", it looks right then. – mSatyam Nov 04 '19 at 17:57
  • Thanks @Mat for the right direction – mSatyam Nov 04 '19 at 18:00

0 Answers0