模板的前置声明
template <typename> class Foo;
template <typename T>
bool operator==(const Foo<T>&, const Foo<T>&);
友元的声明
一对一友好关系
template <typename> Foo;
template <typename T>
bool operator==(const Foo<T> &, const Foo<T> &);
template <typename T>
class Object
{
// 每个Object实例将访问权限授予用相同类型实例化的Foo和相等运算符
friend class Foo<T>;
friend bool operator==<T>(const Foo<T> &, const Foo<T> &);
};
通用和特定的模板友好关系
template <typename T> class Pal;
class C
{
// 用类C实例化的Pal是C的一个友元
friend class Pal<C>;
// Pal2的所有实例都是C的友元; 这种情况无需前置声明
template <typename T> friend class Pal2;
};
template <typename T> class C2
{
// C2的每个实例将相同实例化的Pal声明为友元; Pal的模板声明必须在作用于之内
friend class Pal<T>;
// Pal2的所有实例都是C2的每个实例的友元,不需要前置声明
template <typename X> friend class Pal2;
// Pal3是一个非模板类, 它是C2所有实例的友元
friend class Pal3;
};
为了让所有实例成为友元, 友元声明中必须使用与类模板本身不同的模板参数.
令模板自己的类型参数成为友元(c++11)
template <typename Type>
class Bar
{
friend Type; // 将访问权限授予用来实例化Bar的类型
};
虽然友元通常来说应该是一个类或是一个函数,但我们完全可以用一个内置类型来实例化Bar.这种与内置类型的友好关系是允许的,以便我们能用内置类型来实例化Bar这样的类.
模板类型别名(c++11)
为类模板定义一个类型别名:
template <typename T> using twin = std::pair<T, T>;
template <typename T> using partNo = std::pair<T, unsigned>;
一个模板类型别名是一族类的别名.
当我们定义一个模板类型别名时,可以固定一个或多个模板参数