vendredi 30 octobre 2015

Extern template and member templates

//A.hpp:

#ifndef A
#define A
#include <iostream>

template <typename T> class A{
public:
    template <typename U> void huh(U a) { cout << "Yello? You'll have to speak up I'm wearing a towel." << endl;}
    T name;
};

#endif

//test.cpp:

#include "A.hpp"

extern template class A<string>;

int main(){
    A<string> a;
    a.huh(2)
}


//instantiate.cpp:

#include "A.hpp"

template class A<string>;

This compiles fine on gcc 4.8.1. So is this really a valid program? My concern comes from the fact that a.huh(2) is called, where huh is a member template of an explicitly instantiated class template. There was no explicit instantiation for huh<int> anywhere in my program despite it being a member template. When the compiler sees a.huh(2), does the compiler still generate code for huh<int> in test.cpp despite the fact that code for the class A<string> isn't even generated in that same translation unit? I'd find it quite odd that class member function code could be defined in a translation unit where the class code isn't even generated, but this seems to be a completely valid thing to do? I would really have expected to have to put something like this in instantiate.cpp before it could compile:

//instantiate.cpp:

#include "A.hpp"

template class A<string>;
template void A<string>::huh(int); //not necessary apparently?

(However, if I make huh an ordinary function (no templates) then the compiler will not accept the code, so it must be special to member templates).

Aucun commentaire:

Enregistrer un commentaire