模板友元化
2007-03-16 21:57:45 来源:WEB开发网核心提示: 则,友元就是该函数模板的特化,模板友元化(3),4、否则,该友元必须在全局命名空间内(unqualified,那么该命名将被覆盖——因为存在一个非模板的函数意味着#2优先于#3,看起来有点儿小聪明似的,译者:我将unqualified理解为处于全局命名空间,不知对否
则,友元就是该函数模板的特化。
4、否则,该友元必须在全局命名空间内(unqualified。译者:我将unqualified理解为处于全局命名空间,不知对否。),而且声明为(或重新声明)一个常规函数(非模板)。
很明显,#2和#4只匹配非模板函数,因此我们有2个选择来将某个模板的特化声明为友元:写成#1的形式,或者写成#3的形式。在我们的例子中,可选择如下:
//源代码,合法,因为它符合#3的形式
friend void boost::checked_delete( Test* x );
或者
// 增加了"<Test>",合法,
// 因为5它符合#1的形式
friend void boost::checked_delete<Test>( Test* x );
前者是后者的简化形式...但只有在该名字处于某一作用域(此例为boost::)中,而且其作用域中必须不存在与其匹配的非模板函数。两者都是合法的,但是前者运用了友元声明规则中的晦涩之处,它会令使用它的人感到困惑——对当前的大多数编译器来说!——下边阐述了为何要求避免使用它的三个原因。
为什么避免#3
有以下几个原因,即使其技术是合法的:
1、#3并不总能正常工作。
如上所述,它是一个以<>清楚地命名了模板参数的简化形式,但是该形式只有在——被某个类或者命名空间限定,而且其作用域中不存在与其相匹配的非模板函数——时,才正常工作。 特别地,如果命名空间中有一个(尤其是以后才加入的!)一个匹配的非模板函数,那么该命名将被覆盖——因为存在一个非模板的函数意味着#2优先于#3。看起来有点儿小聪明似的,却很令人惊讶吧?很容易出错吧?让我们避免这样的小聪明吧。
更多精彩
赞助商链接