undefined reference to template function

86,990

Solution 1

The implementation of a non-specialized template must be visible to a translation unit that uses it.

The compiler must be able to see the implementation in order to generate code for all specializations in your code.

This can be achieved in two ways:

1) Move the implementation inside the header.

2) If you want to keep it separate, move it into a different header which you include in your original header:

util.h

namespace Util
{
    template<class T>
    QString convert2QString(T type , int digits=0);
}
#include "util_impl.h"

util_impl.h

namespace Util
{
    template<class T>
        QString convert2QString(T type, int digits=0)
        {
            using std::string;

            string temp = (boost::format("%1") % type).str();

            return QString::fromStdString(temp);
        }
}

Solution 2

You have 2 ways:

  1. Implement convert2QString in util.h.

  2. Manually instantiate convert2QString with int in util.cpp and define this specialization as extern function in util.h

util.h

namespace Util
{
    template<class T>
    QString convert2QString(T type , int digits=0);

    extern template <> QString convert2QString<int>(int type , int digits);
}

util.cpp

 namespace Util {
     template<class T>
     QString convert2QString(T type, int digits)
     {
         using std::string;

         string temp = (boost::format("%1") % type).str();

         return QString::fromStdString(temp);
     }

     template <> QString convert2QString<int>(int type , int digits); 
}
Share:
86,990

Related videos on Youtube

Vihaan Verma
Author by

Vihaan Verma

Updated on November 14, 2020

Comments

  • Vihaan Verma
    Vihaan Verma over 3 years

    I have three files . The contents of main.cpp are

    #include<iostream>
    #include<QString>
    
    #include "util.h"
    
    int main()
    {
        using Util::convert2QString;
    
        using namespace std;
        int n =22;
        QString tmp = convert2QString<int>(n);
    
        return 0;
    }
    

    util.h

    namespace Util
    {
        template<class T>
        QString convert2QString(T type , int digits=0);
    }
    

    util.cpp

    namespace Util
    {
        template<class T>
            QString convert2QString(T type, int digits=0)
            {
                using std::string;
    
                string temp = (boost::format("%1%") % type).str();
    
                return QString::fromStdString(temp);
            }
    }
    

    When I try to compile these files with following command I get undefined reference error

    vickey@tb:~/work/trash/template$ g++ main.cpp  util.cpp -lQtGui -lQtCore  -I. -I/usr/local/Trolltech/Qt-4.8.0/include/QtCore -I/usr/local/Trolltech/Qt-4.8.0/include/QtGui -I/usr/local/Trolltech/Qt-4.8.0/include
    /tmp/cca9oU6Q.o: In function `main':
    main.cpp:(.text+0x22): undefined reference to `QString Util::convert2QString<int>(int, int)'
    collect2: ld returned 1 exit status
    

    Is there something wrong with the template declaration or implementation ? why M I getting these linking errors :?

  • Matteo Italia
    Matteo Italia almost 12 years
    Many people use the .tcc extension for the template implementation files.
  • lashgar
    lashgar almost 4 years
    First time I hear .tcc