Question

If I have a class template and I use a smart pointer to a dynamically allocated instance of a specialized instance, does that cause the entire class template to be defined by the complier or will it also wait for a member function to be called from the pointer before it is instantiated?

template <class T>
class Test {
    public:
        void nothing();
        void operation();

        static const int value;
};

template <class T>
const int Test<T>::value = 100;

template <class T>
void Test<T>::nothing() {
   /* invalid code */
   int n = 2.5f;
}

template <class T>
void Test<T>::operation() {
    double x = 2.5 * value;
}

int main() {
    std::unique_ptr<Test<int>> ptr = new Test<int>();  // mark1
    ptr->operation(); // mark2
    return 0;
}
  1. Does the entire class template get instantiated at mark1?

  2. If not does that mean this code will compile correctly and the member function Test::nothing() not be instantiated?

Was it helpful?

Solution 3

So as it turns out for the compiler I'm using (MS Visual C++), my supposition was correct that, for the code as presented in the question, the class template member instantiation would not take place at //mark1 but rather at //mark2 and Test<int>.nothing() would not be created by the compiler.

However, it seems I left out a critical part of the issue that I was experiencing. My actual class was a part of a virtual hierarchy, and according to the MSDN help library all virtual members are instantiated at object creation. So in the example above, if both member functions, i.e. operation() and nothing(), are virtual then at //mark2 the compiler would try to generate code for both functions and the validation of nothing() would fail.

http://msdn.microsoft.com/en-us/library/7y5ca42y.aspx

http://wi-fizzle.com/howtos/vc-stl/templates.htm#t9

OTHER TIPS

Does the entire class template get instantiated at mark1?

Yes. The class template is implicitly instantiated — only the class template, not all its members.

If not does that mean this code will compile correctly and the member function Test::nothing() not be instantiated?

The not doesn't imply that, rather if nothing() is not used, it is not instantited.

The full answer to this probably depends highly on what compiler you are using.

At //mark1, the compiler will notice that at least portions of the Test<int> class need to instantiated. Whether or not it does it right then, or in a later phase, is up to the compiler designer.

At //mark2, Test<int>.operation() is obviously needed, it is either marked for later instantiation or created on the spot, again depending on what the compiler designers decided.

Since Test<int>.nothing() is never referenced, the compiler has the freedom to instantiate it or not. Some older compilers blindly instantiated the entire class, but I suspect the majority of modern compilers will only instantiate what they can prove to be necessary (or at least that they can't prove is not necessary). Again, though, where that happens within the compiler depends on the way the compiler designers built the compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top