1

I have a problem with the linking of a C++ project and I can't figure out what's wrong. The jest of the code.

clitest.cpp

#include <iostream>
#include "node.h"
using namespace std;

int main(int argc, char** argv)
{
    node<int> *ndNew = new node<int>(7);
    return 0;
}

node.h

#ifndef NODE_H
#define NODE_H
#include <vector>

template <typename T>
class node
{
    private:
        node<T>* ndFather;
        std::vector<node<T>* > vecSons;
    public:
        T* Data;
        node(const T &Data);
};
#endif

node.cpp

#include "node.h"

using namespace std;

template <typename T>
node<T>::node(const T &Data)
{
    this->Data = &Data;
    this->ndFather = 0;
    this->vecSons = (new vector<T>());
};

The compiler command that was used is

g++ -Wall -g clitest.cpp node.cpp -o clitest

The error log is goes like this

clitest.cpp: In function ‘int main(int, char**)’:
clitest.cpp:8:16: warning: unused variable ‘ndNew’ [-Wunused-variable]
     node<int> *ndNew = new node<int>(7);
                ^
/tmp/cc258ryG.o: In function `main':
clitest.cpp:8: undefined reference to `node<int>::node(int const&)'
collect2: error: ld returned 1 exit status
make: *** [blist] Error 1

I have spent a decent amount of time shifting the code around, Trying to identify the problem and I either miss something basic, Or it's something I don't know about C++ linkage.

  • 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) – Andy Prowl May 14 '13 at 19:04

2 Answers2

0

Use -I. before the .cpp files, so that the compiler knows to look for .h files.

g++ -Wall -I. clitest.cpp node.cpp -o clitest

Or just -I:

g++ -Wall -I clitest.cpp node.cpp -o clitest
Christopher Bales
  • 1,069
  • 1
  • 13
  • 23
  • The linker answers with: clitest.cpp:(.text+0x31): undefined reference to `node::node(int const&)' I really don't know if that extra flag I've never heard of made any difference. – Guy Shepherd May 14 '13 at 19:18
0

When using templates, the compiler needs to know how to generate the code for the class when it is instantiated. The undefined reference error is caused because the compiler did not generate the node<int>::node(int const &) constructor. See, e.g. Why can templates only be implemented in the header file?

You have a couple of options:

  1. Put the implementation in node.h (node.cpp is removed as it not needed)
  2. Put the implementation in a file that is #included at the bottom of node.h (usually the file would be called node.tpp)

I suggest putting the implementation in node.h and removing node.cpp. Note that the code in your example is not valid c++: the member variable vecSons is not a pointer so the line vecSons = new vector<T>() will give a compiler error. The following code could be a starting point for the full implementation:

#ifndef NODE_H
#define NODE_H
#include <vector>

template <typename T>
class node
{
    private:
        node<T>* ndFather;
        std::vector<node<T>* > vecSons;
    public:
        const T* Data;
        node(const T &d) : 
            ndFather(0),
            vecSons(),
            Data(&d)
        {
        }
};
#endif
Community
  • 1
  • 1
Joe
  • 36
  • 2