3

so i got an undefined reference error when using template explicit instantiation with full template class specialization, but the question is, partial template class specialization goes well without error.

code shows as below, do anyone know why? what's the difference between full specialization and partial specialization in this situation?

Thanks in advance.

// t.h
#include <iostream>

using namespace std;

template <typename T1, typename T2> 
class A { 
  public:
  void foo();
};

// t2.cpp
#include "t.h"

template<typename T1> 
class A<T1, int> {
  public:
  void foo() {
    cout << "T1, int" << endl;
  }
};

template<>
class A<int, int> {
  public:
  void foo() {
    cout << "int, int" << endl;
  }
};

template class A<float, int>;
template class A<int, int>;

// t.cpp
#include "t.h"

int main() {
  A<float, int> a;
  a.foo();  // no error
  A<int, int> a1; 
  a1.foo(); // undefined reference error, why?
  return 0;
}

the compile commands are g++ t.cpp t2.cpp -o t with gcc 4.8.5.

Niu Chong
  • 39
  • 6

1 Answers1

2

You have to declare partial and explicit specializations in every translation unit that uses them (before any use that would implicitly instantiate that specialization). Here, that would look like

template<class T> class A<T,int>;
template<> class A<int,int>;

immediately after the primary template (to avoid any possibility of erroneous implicit instantiation.

Compilers have historically been “lax” about this, which is to say that sometimes it does what you’d expect from an analysis of all source files together.

You’ve found the edge of such accidental “support” in this particular compiler.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • Can you show me how to modify the code above to fulfill the standardization? that is, how to declare partial and explicit specialization in every translation unit? thanks in advance – Niu Chong Mar 05 '19 at 09:39
  • @NiuChong: Since you can declare them and then define them, you can do it just once in the header: edited. – Davis Herring Mar 05 '19 at 16:02
  • i added the code you gave at the end of the header file, but it got another error of 'error: aggregate ‘A a’ has incomplete type and cannot be defined' – Niu Chong Mar 06 '19 at 06:13
  • @NiuChong: Sorry, I was thinking only of preventing the *linker* error. If you need the specializations to be *complete* in (most of) the client translation units, just put the specialization *definitions* in the header, like any other class. – Davis Herring Mar 06 '19 at 06:35
  • thanks, guess i still need to modify the above usage of template class specialization. – Niu Chong Mar 06 '19 at 08:58