一种是scope of the template definition,即定义出template的程序端:
//scope of template definitionexterndoublefoo(double);template<typename type>classScopeRules{public:voidinit(){
_member =foo(_val);}
type type_dependency(){returnfoo(_member);}private:int _val;
type _member;};
另一种是"scope of the template instantiation",即实例化template的程序端。
//scope of template instantiationexternintfoo(int);
ScopeRules<int> sr0;
{P290-291} 假设我们有sr0.invariant() 进而会调用哪一个foo呢? 乍一看,实例化为int,当然是调用int版本的foo了。但实际上调用的是double版本的foo。原因:对于一个nonmember name的决议结果,是根据这个name的使用是否与“用以实例化该template的参数类型”有关而决定的。 如果其使用互不相关,那么就以"scope of T declaration"来决定,否则以"scope of T instantiation"来决定。
这里的invariant调用的是_member = foo(_val);,而_val的类型已经确定了,是int,是一个类型不会变动的template class member。
当一个异常被抛出时,控制权会从函数调用中释放出来,并寻找一个吻合的catch子句(landing pad)。如果都没有吻合者,那么默认的处理例程terminate()会被调用。当控制权被放弃后,堆栈中的每一个函数调用也就被popped up。这个程序被称为unwinding the stack。(退栈?)在每一个函数被退栈之前,函数的local class objects的dtor会被调用。
对EH的支持 {P303}
当一个exception发生时,编译系统必须完成以下事情:
检验发生throw操作的函数。
决定throw操作是否发生在try区段中。
若是,编译系统必须把exception type跟每一个catch子句进行比较。
如果比较吻合,流程控制权应该交到catch子句手中。
如果throw的发生并不在try区段中,或者没有一个catch子句吻合,那么系统必须 :a) 摧毁所有active local objects, b) 从堆栈中将目前的函数unwind掉,c) 进行到程序堆栈的下一个函数中区,重复上述2-5。