ISO/IEC14882:2003之条款14——模板

14、模板

1、一个模板定义了类或函数的一个家

    template-declaration:

                exportopt template < template-parameter-list > declaration

    

    template-parameter-list:

                template-parameter

                template-parameter-list , template-parameter
 

在一个template-declaration中的declaration应该

——声明或定义一个函数或一个类[译者注:比如,

 1 // Declare a function
2 template <typename T>
3 void HelloTemplate(void);
4
5 // Declare a class
6 template <typename T>
7 class TemplateClass;
8
9 // Define a function
10 template <typename T>
11 void HelloTemplate(void)
12 {
13
14 }
15
16 // Define a class
17 template <typename T>
18 class TemplateClass
19 {
20
21 };

],或
 

——定义一个类模板或嵌套在一个类模板中的一个成员函数,成员类,或者是一个静态数据成员[译者注:比如,

 1 // define a member function, a member class and a static data member of 
2 // a class nested within a class template
3 template <typename T>
4 struct A
5 {
6 class B
7 {
8 public:
9 void Func(void);
10 class C;
11 static T var;
12 };
13 };
14
15 template <typename T>
16 void A<T>::B::Func(void)
17 {
18
19 }
20
21 template <typename T>
22 class A<T>::B::C
23 {
24
25 };
26
27 template <typename T>
28 T A<T>::B::var;

],或
 

——定义一个类或类模板的成员模板[译者注:比如,

// Define a member template of a class template
template <typename T>
struct A
{
template
<typename P>
class B;
};

template
<typename T>
template
<typename P>
class A<T>::B
{
P var1;
T var2;
};

]。

一个template-declaration是一个声明。一个template-declaration也是一个定义,如果其声明定义了一个函数,一个类,或一个静态数据成员。
 

2、一个template-declaration只能作为一个名字空间域或类域声明出现。在一个函数模板声明中,declarator-id应该是一个template-name(即,不是一个template-id)。[注:在一个类模板声明中,如果类名是一个template-id,那么其声明将会声明一个类模板部分特化(14.5.4)。][译者注:template-name以及template-id详细请见条款14.2。]
 

3、在一个template-declaration,显式的特例化或显式的实例化中,声明中的init-declarator-list应该最多只能包含一个声明符。当这样的一个声明被用于声明一个类模板时,不允许有任何声明符。[译者注:比如,

 1 template <typename T>
2 struct A
3 {
4
5 }a; // Error
6
7 template <typename T>
8 struct B
9 {
10 static T a, b;
11 };
12
13 template <typename T>
14 T B<T>::a, B<T>::b; // Error
15
16 struct C
17 {
18 static int c, d;
19 };
20
21 int C::c = 10, C::d = 20; // OK


 

4、一个模板具有连接(3.5)。一个非成员函数模板可以具有一个内部连接;任何其它模板名应该有外部连接。从一个具有内部连接的模板所生成的实体与在其它翻译单元所生成的所有实体是截然不同的。一个模板,一个模板显式特化(14.7.3),或一个类模板部分特化不应该具有C连接。如果这些其中的某个连接并不是C或C++的,那么行为是由实现定义的。模板定义应该遵循一次定义规则(3.2)。[注:函数模板的默认实参以及类模板的成员函数的默认实参被认为是出于模板实例化(14.5)目的的定义,并且也必须遵循一次定义规则。]

5、 一个类模板不该与任何其它模板,类,函数,对象,枚举,枚举符[译者注:

enum MyEnum    // enumeration(枚举)
{
VALUE
// enumerator(枚举符)
};

],名字空间,或在同一作用域中的类型具有相同的名字(3.3),除了在(14.5.4)中所指定的之外。除了一个函数模板可以被带有相同名字的(非模板)函数,或是带有相同名字的其它函数模板重载(14.8.3)以外,一个在名字空间作用域或在类作用域中所声明的模板名在那个作用域中应该是唯一的。

6、一个非内联函数模板,一个非内联成员函数模板,一个类模板的一个非内联成员函数,或一个类模板的一个静态数据成员,的一个名字空间作用域的声明或定义之前可以加关键字export。如果这样的一个模板在同一翻译单元中被定义,而在此翻译单元中,使用了export对它进行声明,那么此定义被认为是输出的。 包含export关键字的模板的第一次声明不能跟在定义后面。

7、声明一个被输出的类模板等价于声明其所有的非内联函数成员,静态数据成员,成员类,成员类模板以及非内联函数模板成员,这些都定义在那个被输出的翻译单元中。

8、 被定义在一个未命名的名字空间中模板不应该被输出。一个模板在一个程序中只能被输出一次。不要求一个实现必须诊断对这个规则的违背。一个非输出的模板必须在每个它被隐式实例化(14.7.1)的翻译单元中定义,除非相应的特化在某些翻译单元中被显式地实例化(14.7.2);这里不要求诊断。[注:见14.7.2] 一个被输出的模板在它被实例化的一个翻译单元中只需要被声明(而不需要被定义)。一个同时被声明了输出和内联的函数模板只是内联的而非输出的。

9、[注:一个实现可以要求一个包含了一个输出模板定义的翻译单元在任一包含了那个模板的一个实例化的翻译单元之前被编译。]


posted @ 2011-09-01 23:44  zenny_chen  Views(842)  Comments(0Edit  收藏  举报