[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Linking error with a template based class in C++

Posted on 2003-10-21
6
Medium Priority
?
240 Views
Last Modified: 2010-04-17
Hi All,

I have been facing a peculiar linking error with my template class on both GNU C++
compiler and Visual C++ compiler. Can anybody help me in this regard. It is a part
of my project work and any help will be highly appreciated. Error encountered and source codes are given below

Thanks in advance

Siddhartha



Compilation
-----------
g++ -c atmplane.cpp   -> creates file atmplane.o
g++ -c test.cpp       -> creates file test.o

Linking
-------

g++ -o atmplane.o test.o
g++ -o test.o atmplane.o

Both these commands give following error
----------------------------------------

test.o: In function `main':
test.o(.text+0x12): undefined reference to `ATMPlane<int>::ATMPlane(int, int)'
test.o(.text+0x26): undefined reference to `ATMPlane<int>::~ATMPlane(void)'
collect2: ld returned 1 exit status



A Win32 console application created in Visual C++ 6.0 with the same files also
give the same linking error


--------------------Configuration: Test - Win32 Debug--------------------
Compiling...
atmplane.cpp
test.cpp
Linking...
test.obj : error LNK2001: unresolved external symbol
"public: __thiscall ATMPlane<int>::~ATMPlane<int>(void)" (??1?$ATMPlane@H@@QAE@XZ)
test.obj : error LNK2001: unresolved external symbol
"public: __thiscall ATMPlane<int>::ATMPlane<int>(int,int)" (??0?$ATMPlane@H@@QAE@HH@Z)
Debug/Test.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

Test.exe - 3 error(s), 0 warning(s)

-----------------------------------------------------------------------------

---------------------------
Source codes are as follows
---------------------------


/******** File Name - atmplane.h *************/

#ifndef ATM_PLANE_H

#define ATM_PLANE_H

template <class T> class ATMPlane
{
      private :
            int _iNum1, _iNum2;
            T _tObj;
      public:
            ATMPlane(int, int);
            ~ATMPlane();
};

#endif


/******** File Name - atmplane.cpp *************/

#include "atmplane.h"

template <class T> ATMPlane<T>::ATMPlane(int iNum1, int iNum2)
{
      _iNum1 = iNum1;
      _iNum1 = iNum2;
}

template <class T> ATMPlane<T>::~ATMPlane()
{
      
}

/******** File Name - test.cpp *************/

#include "atmplane.h"

int main(int argc, char *argv[])
{
      ATMPlane<int> atm(3,2);      
      return 0;
}
0
Comment
Question by:siddhartha_ghosh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
6 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 1000 total points
ID: 9597400
Template class implementation should be kept entirely in h-file. You have two ways:
1) Place function bodies inside of class definitions
2) Place function bodies after class definition in the same h-file.

Template class functions cannot be implemented in separate cpp file.

This happens because C++ compiler makes actual template compilation only when template is instantiated. When this happens, compiler needs all template functions to be available. They shouls be defined in h-file or in the same cpp file. Only linker has access to different cpp file.

In your case, atmplane.cpp doesn't produce any real code (because it is created by compiler only when template is instantiated).
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9597419
By the way, this is a reason template classes cannot be kept in Dll and lib files. All template libraries (like STL, ATL) are supplied in h-files, so that client has full access to their source code. I don't think that library writers like this, but this is only way.

So, remove atmplane.cpp class and add all it's code to atmplane.h:

#ifndef ATM_PLANE_H

#define ATM_PLANE_H


template <class T> class ATMPlane
{
    private :
         int _iNum1, _iNum2;
         T _tObj;
    public:
         ATMPlane(int, int);
         ~ATMPlane();
};

template <class T> ATMPlane<T>::ATMPlane(int iNum1, int iNum2)
{
    _iNum1 = iNum1;
    _iNum1 = iNum2;
}

template <class T> ATMPlane<T>::~ATMPlane()
{
   
}

#endif
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10319470
I think my answer is OK.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Make the most of your online learning experience.
Progress
Introduction to Processes

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question