This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: template specialization problem

  typedef void (*C)();  
  template<class T> struct A  
    static C d;  
    static void Fn();  
    void Fn1();  
    void Fn2();  

  template<class T> C A<T>::d = &Fn; 
  template<class T> void A<T>::Fn(){} 
  template<class T> void A<T>::Fn1(){Fn2();}  
  template<class T> void A<T>::Fn2(){Fn1();}  

  template<> C A<unsigned>::d = &Fn;   
  template<> void A<unsigned>::Fn(){}  
  template<> void A<unsigned>::Fn1(){Fn2();}  
  template<> void A<unsigned>::Fn2(){Fn1();}  

  template class A<unsigned>;

You complain that this results in the errors:

  test.C:16: specialization of A<unsigned int>::Fn() after instantiation
  test.C:16: explicit specialization of A<unsigned int>::Fn() after first use
  test.C:18: specialization of A<unsigned int>::Fn2() after instantiation
  test.C:18: explicit specialization of A<unsigned int>::Fn2() after first use

While you are correct in asserting that these messages would be more
helpful if they indicated where the previous instantiation had
occurred, you are incorrect in asserting that the error messages
themselves are in error.  For example, the call to Fn2 in
A<unsigned>::Fn1 triggers the instantiation of Fn2.

The correct way to write what you want is like this:

  template <class T> void f();
  template <class T> void g();

  template <> void f<int>();
  template <> void g<int>();
  template <> void f<int>() { g<int>(); }
  template <> void g<int>() { f<int>(); }

That lets the compiler know that f<int> and g<int> are being
specialized before they are instantiated.

Mark Mitchell
Mark Mitchell Consulting

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]