Explicit instantiantion of template member in cpp file doesn't generate symbol (i.e. link error)

Viewed 68

Take the following example:

// A.h
class A
{
public:
    int v = 2;

    template <typename T>
    int f(T t);
};
// A.cpp
#include "A.h"

template <typename T>
int A::f(T t)
{
    return v + t;
}

template <>
int A::f<int>(int t);
// main.cpp
#include <stdio.h>

#include "A.h"

int main()
{
    A a;
    printf("%d\n", a.f(3));
    return 0;
}

When building this with clang -std=c++14 (or g++), I get the following error:

main.cpp:8: undefined reference to `int A::f<int>(int)'

Indeed, nm A.o doesn't show any symbols. Why didn't the explicit instantiation of A::f<int> inside A.cpp actually instantiate the function?

1 Answers

I think @JaMiT got the answer.

template <> int A::f<int>(int t)
{
    // full specialization of templated thing
}

Is a full specialization.

template <> int A::f<int>(int t);

Is a declaration that such a specialization exists, but doesn't provide the definition.

The form you want is

 template int A::f<int>(int t);

Which is an instantiation of the member function.

Related