令人费解的偏特化

偏特化是C++ 泛型(STL)中的一个技术,直到去年年底我才知道有这么个东西,觉得非常的神奇,不过想把它用上还真不是件容易的事情。

首先,什么是偏特化。在下面的代码中:


template<typename T, typename U>
inline T function(T a, U b) {
  return a * b;
}

template<typename T>
inline T function<T, int> (T a, int b) {
  return a * b;
}

function<T, int>即是对function的一个特化。当我们调用function(double, double)时,原function会被使用。但如果我们使用function(double, int)则会自动使用特化的function<T, int>。简单说,偏特化就是对某一个泛型参数的特例进行特殊处理。

还有一种特化,比如:


template<typename T, typename U>
inline T function<T, U*> (T a, U* b) {
  return a * (*b);
}

即是对U的类型特化。当我们调用function(double, int*)时,会调用function<T, U*>

看起来这样非常美好,但是如下的代码却不能正确通过连接。


template<typename T>
inline T function_err(T a) {
  return a * a;
}

template<>
inline int function_err<int> (int a) {
  return a * a;
}

看起来function_errfunction没有任何本质区别,都有一个关于int的偏特化。但是一旦该头文件被使用于多个目标文件时,连接这些目标文件就会出现特化函数的多重定义错误。

虽然我很明白这里的问题,由于function_err的特化已经没有任何泛型,它实际上就是一个普通函数,因而编译时编译器就不能正确处理该函数的泛型定义,导致了目标文件中的多重定义。如果把特化定义成简单函数就能通过连接。


template<typename T>
inline T function_ok(T a) {
  return a * a;
}

inline int function_ok(int a) {
  return a * a;
}

简单的看,这好像违背了偏特化的定义。实际上,这里的确没有偏特化,而是简单函数重载了泛型函数。由于重载有更明确地类型定义,因而会被首先使用,效果上等同于偏特化。重载有inline修饰,连接器就能正确本地连接。以上代码能正确编译连接。

综上所述,即使偏特化,也不能将所有的泛型参数都明确特化,而只能部分特化。如果明确特化,则需使用普通函数重载。另外,对于类和结构体的偏特化则不存在上述问题。(怎么看我都觉得是个编译器的bug)

由于过于奇怪,特此记录。

Advertisements

英国4月6日后即将施行的移民政策

4月5日后英国的移民政策又将做出些改变。自己读了相关文档后,总结如下:

1. PSW (Post Study Worker)将在4月6日后关闭。(取而代之,刚毕业的学生需要申请T2,见下面)

2. 在申请时持有T4签证的学生在申请T2签证时,其雇用单位不需要进行劳动力市场测试,也不需要申请受限CoS(也就是说不受每年的T2限额限制,实际上所有在英国持T1-T4的申请者都不受此限额限制)。关于市场测试的具体说明参看最后的附注。

3. 2011年4月6日之后申请T2的临时技术移民(temporary skilled worker)仍可在5年后申请永居(settlement),但是必须证明自己的年工资在35,000英镑以上(也就是2016年4月后申请永居的人。2018年4月之前此工资限制不变,2018年之后的工资限制会于2013年公布)。紧缺工作和PhD水平工作不受此限制(不太确定我的RA工作是否是PhD水平工作)。

4. 2012年4月6日之后申请T2的临时技术移民将使用3+3模式。即第一次最多获得3年签证,第二次仍可获得最多3年的T2签证。但如果在第6年签证到期时,未能转入永居,只能离开英国(也许能转T1或T4)。在6年的T2过期后的12个月内(冷却期),不得重新申请T2签证。

 

总结三点:1. 我也许需要在5年内争取35,000英镑的工资;2. T2持有者3年后找新工作可能变难了,因为刚毕业的学生不需要劳动力市场测试;3.4月5日后毕业的学生需要在学生签证过期前找到工作,不过过的该工作的条件显然降低了,对好学生来说是个好消息。

附录:摘自将于2012年4月6日后生效的T2雇佣者的政策说明(Policy guidance for T2 and T5 sponsors

288. A resident labour market test is not required where a migrant currently has permission to
stay in the UK under:
a) Tier 1 (Post-study work); or
b) the International Graduates Scheme; or
c) the Fresh Talent Working in Scotland Scheme; or
d) the Science and Engineering Graduates Scheme;
or where
e) the migrant has current leave to be in the UK as a doctor or dentist in Speciality Training
and they need to apply for further leave under Tier 2 (General) so that they can complete
that training or return to that training after an out of programme experience (see
paragraphs 310-313 on postgraduate doctors and dentists); or
f) the gross annual salary package for the job will be £150,000 or above; or
g) The migrant currently has permission to stay in the UK as a Tier 4 migrant or as a
Student and they have received final results confirming that they have passed and will be
(or have been) awarded:
I. a UK recognised bachelor or postgraduate degree; or
II. a UK Postgraduate Certificate in Education; or
III. they have completed a minimum of 12 months study in the UK towards a UK PhD.

其中蓝色加粗的部分即说明学生不需要劳动力市场测试。