第2章 类模板:2.4 友元

半世苍凉 提交于 2020-04-16 07:25:30

【推荐阅读】微服务还能火多久?>>>

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 << ’\n’; // OK
std::cout << ps.top().second << ’\n’; // OK
std::cout << ps << ’\n’; //错误: 元素类型不支持operator<< 操作
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!