ISO/IEC14882:2003之条款14.2——模板特化的名字

14.2 模板特化的名字


1、一个模板特化(14.7)可以被一个template_id所引用:

    template-id:

        template-name < template-argument-listopt >


    template-name:

        identifier


    template-argument-list:

        template-argument

        template-argument-list , template-argument


    template-argument:

        assignment-expression

        type-id

        id-expression


[注:名字查找规则(3.4)用于将一个名字的使用与一个模板声明关联起来;即,将一个名字标识为一个template-name。]


2、对于被模板实参显式限定的一个template-name,该名字必须被获悉引用了一个模板。


3、在名字查找(3.4)发现一个名字是template-name之后,如果这个名字后面跟着一个<,那么这个<总是被采取为一个template-argument-list的开始,而不会被采纳为一个小于操作符。当解析一个template_id时,第一个非嵌套的>[注:围住一个dynamic_cast、static_cast、reinterpret_cast或const_cast的type-id的一个>,或是围住一个后续template_id的一个template-argument的一个>,被认为是用于此描述的目的而嵌套的]被采纳为template-argument-list的结束,而不是一个大于操作符。[例:

template <int i> class X { /* ... */ };

X
< 1>2 > x1; // 语法错误
X< (1>2) > x2; // OK

template
<class T> class Y { /* ... */ };
Y
< X<1> > x3 // OK
Y <X<6>> 1> > x4; // OK: 相当于Y< X< (6 >> 1)> >

——例结束][译者注:

template <typename T>
struct A
{

};

template
<int N>
struct B
{

};

extern "C" void cpp_test(void)
{
A
<B<100>> a; // error: 相当于A< B< (100 >> a);

A
< B<100> > a; // OK: 其中,第一个>是嵌套的
}


4、当一个成员模板特化的名字出现在一个后缀表达式中的.或->之后,或是在一个qualified-id中的nested-name-specifier之后,并且后缀表达式或qualified-id显式地依赖于一个模板形参(14.6.2)时,成员模板名前必须添加关键字template。否则,该名字被假定命名了一个非模板。[例:

class X {
public:
template
<size_t> X* alloc();
template
<size_t> static X* adjust();
};
template
<class T> void f(T* p)
{
T
* p1 = p->alloc<200>(); // 不良形式的:<意思是小于

T
* p2 = p->template alloc<200>(); // OK: <作为模板实参列表的开始

T::adjust
<100>(); // 不良形式的: <意思是小于

T::template adjust
<100>(); // OK: <作为模板实参列表的开始
}

——例结束]


5、如果加了关键字template前缀的一个名字不是一个成员模板的名字,那么程序是不良形式的。[注:关键字template不可以被提供给类模板的非模板成员。]此外,成员模板的名字不应该加关键字template最为前缀,如果postfix-expressionqualified-id没有出现在一个模板的作用域中。[注:就如同是在带有typename前缀的情况下,template前缀在其并非严格必要的情况下是被允许的;即,当->或.的左边的表达式,或nested-name-specifier并不依赖于一个template-parameter时]

[译者注:

template <typename T>
struct A
{
void f(void) const
{

}

template
<typename Q>
struct I { };
};

template
<typename T>
struct B
{
void f(const T& t)
{
t.f();
// OK

t.template f();
// 不良形式的

typename T::template I
<int>(); // OK
}
};

extern "C" void cpp_test(void)
{
A
<int> a;
B
< A<int> >().f(a);

A
<int>::I<char>(); // OK
A<int>:: template I<char>(); // 不良形式的,在模板的作用域外
}


6、命名一个类模板特化的一个template-id是一个class-name(条款9)。

posted @ 2011-09-04 14:07  zenny_chen  Views(517)  Comments(0Edit  收藏  举报