-1

Please read this first:

Storing C++ template function definitions in a .CPP file

This is what I am attemptng here.

I used the first method from this site to define a template class in a cpp file:

http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp

It looks like this:

b.h :

#ifndef B_H_
#define B_H_
class B  
{
public:
    B();
};
#endif

a.h :

#ifndef A_H_
#define A_H_
template<class T>
class A  
{
public:
    A();
    int get();

private:
    int val;
};
#endif

a.cpp

#include "a.h"

template <class T>
A<T>::A()
{
}

template <class T>
int A<T>::get()
{
    return 42;
}

// No need to call this TemporaryFunction() function,
// it's just to avoid link error.
void TemporaryFunction ()
{
    TestTemp<B> TempObj;
}

main.cpp

#include "a.h"
int main(int argc, char** argv){    
    A<B> ab;
    ab.get();
}

I have to change get to virtual or I get:

undefined reference to `A::get()'

I don't understand this. This is just a sample of the real code (that is too large). If it does not reproduce, I will provide more details tomorrow.

gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)

Community
  • 1
  • 1
AturSams
  • 7,568
  • 18
  • 64
  • 98
  • 3
    Yet another chapter in the book of "templates don't have external linkage". All code has to go in the header file. – Hans Passant Jan 08 '14 at 22:55
  • 1
    Note your question but still: identifiers starting with an underscore followed by a capital character, e.g., `_B_H`, are reserved for the implementation (i.e., the compiler and its standard library). You are not allowed to use these names unless you are given explicit permission by the C++ standard. – Dietmar Kühl Jan 08 '14 at 22:56
  • Implement template functions in the header. – derpface Jan 08 '14 at 23:14
  • @HansPassant, If you read the link I attached. There is another option. Besides, that does not explain why it works when it is virtual which is my question. – AturSams Jan 08 '14 at 23:15
  • Voting to close as duplicate until you add something to differentiate this from all the other "my template doesn't instantiate" questions. – Casey Jan 08 '14 at 23:50

1 Answers1

1

Template members are either explicitly instantiated or instantiated on demand. You are not explicitly instantiating the template, but rather causing the implicit instantiation of the type and the constructor by means of the local variable. Since you don't use A<B>::get() that function will not be instantiated by the compiler.

If the function is marked as virtual, then it is odr-used just by means of instantiating the object (hint: the address of each virtual function, or a similar piece of information, needs to be stored in the vtable).

That being said, and without reading the article in question, this approach is wrong. You don't need to create the function and cause the instantiation of each member function, but rather use explicit instantiation of the template.

template class A<B>;   // Explicit instantiation
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489