是否可以在C ++中编写不纯的模板?也就是说,模板有时会为相同的模板参数提供不同的结果类型或int。例如,是否可以编写模板Foo<T>
Foo<int>::type
有时char
,有时float
?或模板Foo<T>
,其中Foo<double>::my_static_const_int
有时为10,其他时间为20?
答案 0 :(得分:10)
这是不可能的。如果您的模板具有相同的行为方式,则会违反ODR和/或其他规则,例如在实例化之前应声明特化。因此,您不能只是放置一个专门化,以某种方式更改typedef成员,使其解析为所有后续引用的不同类型。
如果Foo<T>
是类模板,请记住Foo
引用了一个类。如果类的typedef成员在程序中的某一点定义为一种类型,而另一种类型定义为另一种类型,则必然会出现错误。以下是与此相关的各种标准报价
函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点。类模板的专门化在翻译单元中最多只有一个实例化点。任何模板的特化可以在多个翻译单元中具有实例化点。如果两个不同的实例化点根据一个定义规则(3.2)给出模板特化的不同含义,则该程序格式错误,无需诊断。
如果一个模板,一个成员模板或一个类模板的成员被明确地专门化,那么该特化应该在第一次使用该特化之前声明,这将导致隐式实例化发生,在每个翻译单元中使用发生;无需诊断。
(跳过各种“噪音”)
[..可以在整个程序中定义多个的各种实体..]。鉴于在多个翻译单元中定义了这样一个名为D的实体,那么
- D的每个定义应由相同的令牌序列组成;
- 在D的每个定义中,相应的名称,根据3.4查找,应指在D的定义内定义的实体,或者在重载解析(13.3)和匹配部分模板后应引用同一实体专业化(14.8.3)......
- 如果D是模板,并且在多个翻译单元中定义,则最后四个 上面列表中的要求应适用于模板定义(14.6.3)中使用的模板封闭范围中的名称,以及实例化时的相关名称(14.6.2)。如果D的定义满足所有这些要求,那么程序应该表现得就像D的单个定义一样。如果D的定义不满足这些要求,则行为是不确定的。