第2章 类模板:2.4 友元

2.4 Friends

2.4 友元

Instead of printing the stack contents with printOn() it is better to implement toperator<< for the stack. However, as usual operator<< has to be implemented as nonmember function, which then could call printOn() inline:

与其使用printOn()打印栈内容,不如为栈实现operator<<运算符。但是,通常oeraptor<<必须实现为非成员函数,然后以内联方式调用printOn()。

template<typename T>
class Stack {
    …
    void printOn() (std::ostream& strm) const {
        …
    }

    friend std::ostream& operator<< (std::ostream& strm, Stack<T> const& s) {
        s.printOn(strm);
        return strm;
    }
};

Note that this means that operator<< for class Stack<> is not a function template, but an “ordinary” function instantiated with the class template if needed.

注意,这意味着对于Stack<>类的operator<<不是函数模板,而是在需要时根据类模板实例化出来的一个“普通”函数。

However, when trying to declare the friend function and define it afterwards, things become more complicated. In fact, we have two options:

但是,当尝试声明友元函数并在之后定义它时,事情变成更加复杂。实际上,我们有两个选择:

1. We can implicitly declare a new function template, which must use a different template parameter, such as U:

1. 我们可以隐式声明一个新的函数模板,该模板必须使用不同的模板参数(如U):

template<typename T>
class Stack {
    …
    template<typename U>
    friend std::ostream& operator<< (std::ostream&, Stack<U> const&);
};

Neither using T again nor skipping the template parameter declaration would work (either the inner T hides the outer T or we declare a nontemplate function in namespace scope).

再次使用T或不声明模板参数都将不起作用(要么是因为内部T隐藏了外部T,要么是在命名空间作用域内声明非模板函数)

2. We can forward declare the output operator for a Stack<T> to be a template, which, however, means that we first have to forward declare Stack<T>:

我们可以Stack<T>的operator<<运算符声明为模板,但这意味着我们必须先声明Stack<T>:

template<typename T> class Stack;

template<typename T>
std::ostream& operator<< (std::ostream&, Stack<T> const&);

Then, we can declare this function as friend:

然后,我们可以将此函数声明为友元:

template<typename T>
class Stack {
    …
    friend std::ostream& operator<< <T> (std::ostream&, Stack<T> const&);
};

Note the <T> behind the “function name” operator<<. Thus, we declare a specialization of the nonmember function template as friend. Without <T> we would declare a new nontemplate function. See Section 12.5.2 on page 211 for details.

注意,<T>在“函数名称”operator<<的后面。因此,我们将一个特殊的非成员模板函数声明为友元。如果没有<T>,我们声明的是一个新的非模板函数。详见第211页的12.5.2节。

In any case, you can still use this class for elements that don’t have operator<< defined. Only calling operator<< for this stack results in an error:

任何时候,你都可以将此类用于未定义operator<<的元素。仅当该栈调用operator<<时才会出现错误:

Stack<std::pair< int, int>> ps; // std::pair<> 没有定义operator<<
ps.push({4, 5}); // OK
ps.push({6, 7}); // OK

std::cout << ps.top().first << ’
’; // OK
std::cout << ps.top().second << ’
’; // OK
std::cout << ps << ’
’; //错误: 元素类型不支持operator<< 操作
原文地址:https://www.cnblogs.com/5iedu/p/12709003.html