0
votes

I'm working on a project in C++ and am having trouble understanding what members of a template class get explicitly instantiated when I explicitly instantiate the template class. I've written the following file, which I then compile using Visual C++ 2008 Express Edition's Release configuration and then pop into a disassembler.

template<typename T> class test {
public:
    template<typename T> test(T param) {
        parameter = param;
    };
    ~test() {};
    int pop();
    int push();
    T parameter;
};

template<typename T> int test<T>::push() {return 1;}
template<typename T> int test<T>::pop() {return 2;}

template class test<int>;

int main() {
    return 0;
}

Ignoring that this file doesn't really need templates for the moment, this compiles fine. I throw the exe into the disassembler and it tells me that test<int>::pop(void), test<int>::push(void), and test<int>::~test<int>(void) are functions in the exe, but I don't see the constructor. I know I can explicitly instantiate the constructor with

template test<int>::test(int);

which causes test<int>::test<int>(int) to appear in the disassembly as a function with the other ones. My understanding of explicit instantiation is that it is supposed to tell the compiler to instantiate all members of a template class for a given set of arguments, so why is it that the constructor is not explicitly instantiated along with all the other member functions?

1
Your class template is invalid because the constructor's template parameter shadows the class' template parameter. But it's not surprising that the VC++ compiler accepts it silently.Praetorian
How can it instantiate the constructor if its template parameters aren't known?0x499602D2

1 Answers

2
votes

When the constructor is a template member function, they are not instantiated unless explicitly used.

You would see the code for the constructor if you make it a non-template member function.

template<typename T> class test {
public:

    /***
    template<typename T> test(T param) {
        parameter = param;
    };
    ***/

    test(T param) : parameter(param) {}
    ~test() {}
    int pop();
    int push();
    T parameter;
};