6

I'm running into an issue with template specialization. The following builds and runs, but I'm not sure it should:

// template.h
template <typename T>
class interface{
public:
   void doSomething();
};

// template.cpp
#include "template.h"
#include <iostream>
template <> void interface<int>::doSomething(){std::cout << "Did something\n";}

// main.cpp
#include "template.h"
int main(){
   interface<int> instance;
   instance.doSomething();
   return 0;
 };

g++ main.cpp template.cpp; ./a.out

My understanding was that all compilation units were supposed to have access to all template specializations, which main.cpp does not. If I understand what's happening correctly, the specialization in template.cpp also instantiates interface< int >, so the symbol is generated and everything links happily. However, I'm pretty sure this falls into the realm of undefinedness and I can't count on this always working everywhere. Can someone please confirm or deny my suspicions?

Thanks!

Kevin
  • 510
  • 4
  • 16
  • 1
    I think you didn't finish to type your title... – hivert Mar 11 '14 at 19:40
  • Well, first of all you are missing a `;` after the class definition/declaration. – Shoe Mar 11 '14 at 19:44
  • Oops! I'm transcribing from my compiler machine to my internet machine and not doing very well. – Kevin Mar 11 '14 at 19:50
  • It's explicit specialization, so it should be fine, right? –  Mar 11 '14 at 19:56
  • 2
    @πάντα ῥεῖ Thanks -- I know that you can put the template implementation in a separate file as long as you explicitly instantiate, but I thought specializing outside of the view of a compilation unit that needs it was undefined (though now I can't find the section of the standard stating so.) I can't think of a situation where my code _wouldn't_ work, as the specialization and instantiation seem guaranteed to make the correct symbols, but I'm afraid a malicious compiler could refuse to build my code and still be compliant. – Kevin Mar 11 '14 at 20:14
  • @Kevin I read in another question that it provides a complete definition so there's no issue. –  Mar 11 '14 at 20:23
  • 1
    You can work around your concern if you write an explicit specialization declaration in the header, e.g. `template<> class interface;`. Good question, btw. – jrok Mar 11 '14 at 20:23
  • something soomething if a template specialization is not visible at the point of instantiation where that specialization applies something something undefined? – Yakk - Adam Nevraumont Mar 11 '14 at 20:28
  • @jrok `template<> class interface;` is a declaration of a class template specialization. In this case a class template member specialization is used, so the right code for its declaration is: `template <> void interface::doSomething();`. – Constructor Mar 11 '14 at 20:47
  • According to standard you should declare such explicit specializations before their first using. See [this question](http://stackoverflow.com/questions/15061774/template-class-member-specialization-without-declaration-in-header) for details. – Constructor Mar 11 '14 at 20:48

0 Answers0