How is a template instantiated?

北战南征 提交于 2020-02-18 00:31:30

问题


It's an exercise from C++ Primer 5th Edition:

Exercise 16.27: For each labeled statement explain what, if any, instantiations happen. If a template is instantiated, explain why; if not, explain why not. P.677

template <typename T> class Stack { };

void f1(Stack<char>);                   // (a)

class Exercise {
    Stack<double> &rsd;                 // (b)
    Stack<int>    si;                   // (c)
};

int main() {
    Stack<char> *sc;                    // (d)
    f1(*sc);                            // (e)
    int iObj = sizeof(Stack< string >); // (f)
}

Below is what I tried:

(a) Stack<char> is instantiated , but no member of it is instantiated.

(b) Stack<double> is instantiated , but no member of it is instantiated.

(c) Stack<int> and its default constructor are instantiated.

(d) (e) totally no idea...

(f) Stack< string > is instantiated , but no member of it is instantiated.

Am I right? Can anyone tell me how this code is instantiated?


回答1:


In your specific case a declaration doesn't mean an instantiation

#include <iostream>
using namespace std;


template <typename T> class Stack {
  typedef typename T::ThisDoesntExist StaticAssert; // T::NotExisting doesn't exist at all!
};


void f1(Stack<char>); // No instantiation, compiles

class Exercise {
  Stack<double> &rsd; // No instantiation, compiles (references don't need instantiation, are similar to pointers in this)

  Stack<int>    si; // Instantiation! Doesn't compile!!
};


int main(){

  Stack<char> *sc; // No Instantiation, this compiles successfully since a pointer doesn't need instantiation

  f1(*sc); // Instantiation of Stack<char>! Doesn't compile!!

  int iObj = sizeof(Stack< std::string >); // Instantiation of Stack<std::string>, doesn't compile!!

}

notice the pointer/reference stuff: they don't require instantiation since no data is actually allocated (a pointer is just a few bytes to contain the address, has no need to have all the data stored.. take a look at the pimpl idiom ).

Only when stuff is allocated then the template has to be completely resolved (and that happens at compile-time, that's why they usually need both declaration and definition.. there's no linking phase yet)




回答2:


Regarding e and d I will quote the standard 14.7.1

Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument.

Example also from the standard

template<class T> struct Z {
void f();
void g();
};

void h() 
{
Z<int> a;     // instantiation of class Z<int> required
Z<char>* p;   // instantiation of class Z<char> not required
Z<double>* q; // instantiation of class Z<double> not required
a.f();        // instantiation of Z<int>::f() required
p->g();       // instantiation of class Z<char> required, and instantiation of Z<char>::g() required
}

This means that no instantiation happens in d. While it will be instantiated in e if that function actually needed to call a function from that type ( could be a copy constructor or any other function called inside the function).



来源:https://stackoverflow.com/questions/21598635/how-is-a-template-instantiated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!