|
@@ -1101,3 +1101,57 @@ C<void (), &templ_func<double> >* c6; // function template 具现体也是一
|
|
|
2. 浮点值
|
|
2. 浮点值
|
|
|
3. 字符串
|
|
3. 字符串
|
|
|
|
|
|
|
|
|
|
+### 友元
|
|
|
|
|
+
|
|
|
|
|
+友元类的声明不能是类定义,在引入模板之后,友元类声明的唯一变化只是:可以命名一个特定的类模板实例为友元
|
|
|
|
|
+
|
|
|
|
|
+```cpp
|
|
|
|
|
+class TestClass
|
|
|
|
|
+{
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+template<typename T>
|
|
|
|
|
+class Node {
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+template<typename T>
|
|
|
|
|
+class Tree {
|
|
|
|
|
+ friend TestClass; // OK
|
|
|
|
|
+ friend Node<T>; // OK
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```cpp
|
|
|
|
|
+template<typename T>
|
|
|
|
|
+class Tree {
|
|
|
|
|
+ friend TestClass; // Error
|
|
|
|
|
+ friend Node<T>; // Error
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+class TestClass
|
|
|
|
|
+{
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+template<typename T>
|
|
|
|
|
+class Node {
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+显然,如果要把类模板的实例声明为其他类或者类模板的友元,该类模板在声明的地方必须是可见的
|
|
|
|
|
+
|
|
|
|
|
+**友元函数**
|
|
|
|
|
+
|
|
|
|
|
+```cpp
|
|
|
|
|
+template <typename T1, typename T2>
|
|
|
|
|
+void combine(T1, T2);
|
|
|
|
|
+
|
|
|
|
|
+class Mixer {
|
|
|
|
|
+ friend void combine<>(int&, int&); // OK:T1 = int&, T2 = int&
|
|
|
|
|
+ friend void combine<int, int>(int, int); // OK:T1 = int, T2 = int
|
|
|
|
|
+ friend void combine<char>(char, int); // OK:T1 = char T2 = int
|
|
|
|
|
+ friend void combine<char>(char&, int); // ERROR:与 combine() template 不匹配
|
|
|
|
|
+ friend void combine<>(long, long) { ... } // ERROR:不能在此处定义函数
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+不能在友元声明中定义一个模板实例,所以命名一个实例的友元声明不是不行的
|