2

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?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • I did see this answer, which doesn't quite answer it: https://stackoverflow.com/a/115735/912144 – Shahbaz Dec 16 '21 at 07:35
  • Actually, just noticed that with `template A::f...` it works, but not `template<> A::f...`. What's the deal with the lack of `<>`? – Shahbaz Dec 16 '21 at 07:36
  • 2
    With `<>` is [Explicit (full) template specialization](https://en.cppreference.com/w/cpp/language/template_specialization). Without `<>` is [Function template instantiation](https://en.cppreference.com/w/cpp/language/function_template#Function_template_instantiation). Details matter! – JaMiT Dec 16 '21 at 07:42
  • 1
    That's a declaration of a specialization, which is never defined. – molbdnilo Dec 16 '21 at 07:55

1 Answers1

1

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.

mksteve
  • 12,614
  • 3
  • 28
  • 50