• 第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<< 操作
  • 相关阅读:
    GitHub 的企业版
    我的Tag列表
    .net开发者对android开发一周的学习体会
    Ajax简单聊天B/S
    C#设计模式——享元模式(Flyweight Pattern)
    mongodb的sharding架构搭建
    Java设计模式
    LMAX架构
    Winform开发的常用类库
    C#设置本地网络(DNS、网关、子网掩码、IP)
  • 原文地址:https://www.cnblogs.com/5iedu/p/12709003.html
Copyright © 2020-2023  润新知