嵌套模板类的友元函数

cloudblaze 2020-03-28 12:13:17
我写了一个嵌套的模板类,外层类和内层类都有一个重载的operator<<函数用来打印信息。外层类的operator<<函数中调用了内层类的operator<<函数,报告出了 no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const hy::List<int>::Node’) 这样的编译错误。但如果我将内外嵌套的两个类更改成平级的,也就是把内层类实现到外层类之外 ,这样编译和执行都是没问题的。希望哪个大神能帮我看看问题。代码是我从原来的代码简化的,但报告的问题是一样的。谢谢!
List.h:
#ifndef LIST_H
#define LIST_H

#include <iostream>

namespace hy
{
template<typename T>
class List
{
private:
class Node
{
private:
T _Data;
public:
Node();
Node(const Node & node);
Node & operator=(const Node & node);
~Node();

void SetValue(const T & item);

template<typename Type>
friend std::ostream & operator<<(std::ostream & os, const typename List<Type>::Node & node);
};

private:
List<T>::Node _Node;

public:
List();
List(const List<T> & list);
List<T> & operator=(const List<T> & list);
~List();

void SetNode(const T & item);

template<typename Type>
friend std::ostream & operator<<(std::ostream & os, const List<Type> & list);
};

template<typename T>
List<T>::Node::Node()
{

}

template<typename T>
List<T>::Node::Node(const List<T>::Node & node)
{
_Data = node._Data;
}

template<typename T>
typename List<T>::Node & List<T>::Node::operator=(const List<T>::Node & node)
{
if(this == &node)
{
return *this;
}

_Data = node._Data;
return *this;
}

template<typename T>
List<T>::Node::~Node()
{

}

template<typename T>
void List<T>::Node::SetValue(const T & item)
{
_Data = item;
}

template<typename T>
std::ostream & operator<<(std::ostream & os, const typename List<T>::Node & node)
{
os << node._Data;
return os;
}

template<typename T>
List<T>::List()
{

}

template<typename T>
List<T>::List(const List<T> & list)
{
_Node = list._Node;
}

template<typename T>
List<T> & List<T>::operator=(const List<T> & list)
{
if(this == &list)
{
return *this;
}

_Node = list._Node;
return *this;
}

template<typename T>
List<T>::~List()
{

}

template<typename T>
void List<T>::SetNode(const T & item)
{
_Node.SetValue(item);
}

template<typename T>
std::ostream & operator<<(std::ostream & os, const List<T> & list)
{
os << list._Node;
return os;
}
}

#endif


main.cpp:
#include <iostream>
#include "List.h"

int main()
{
hy::List<int> list;
list.SetNode(5566);
std::cout << list << std::endl;

return 0;
}

...全文
175 5 打赏 收藏 举报
写回复
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdghchj 2020-04-14
我服了

template<typename T>
    class List
    {
    private:
        class Node
        {
        private:
            T _Data;
        public:
            Node();
            Node(const Node & node);
            Node & operator=(const Node & node);
            ~Node();

            void SetValue(const T & item);

            friend std::ostream & operator<<(std::ostream & os, const Node & node){
                cout<< node._Data <<endl;
            }
        };

    private:
        List<T>::Node _Node;

    public:
        List();
        List(const List<T> & list);
        List<T> & operator=(const List<T> & list);
        ~List();

        void SetNode(const T & item);

        template<typename Type>
        friend std::ostream & operator<<(std::ostream & os, const List<Type> & list);
    };

    template<typename T>
    List<T>::Node::Node()
    {

    }

    template<typename T>
    List<T>::Node::Node(const List<T>::Node & node)
    {
        _Data = node._Data;
    }

    template<typename T>
    typename List<T>::Node & List<T>::Node::operator=(const List<T>::Node & node)
    {
        if(this == &node)
        {
            return *this;
        }

        _Data = node._Data;
        return *this;
    }

    template<typename T>
    List<T>::Node::~Node()
    {

    }

    template<typename T>
    void List<T>::Node::SetValue(const T & item)
    {
        _Data = item;
    }

    template<typename T>
    List<T>::List()
    {

    }

    template<typename T>
    List<T>::List(const List<T> & list)
    {
        _Node = list._Node;
    }

    template<typename T>
    List<T> & List<T>::operator=(const List<T> & list)
    {
        if(this == &list)
        {
            return *this;
        }

        _Node = list._Node;
        return *this;
    }

    template<typename T>
    List<T>::~List()
    {

    }

    template<typename T>
    void List<T>::SetNode(const T & item)
    {
        _Node.SetValue(item);
    }

    template<typename T>
    std::ostream & operator<<(std::ostream & os, const List<T> & list)
    {
        os << list._Node;
        return os;
    }

int main(int argc,char* argv[]) {
    List<int> list;
    list.SetNode(5566);
    std::cout << list << std::endl;
    return 0;
}


  • 打赏
  • 举报
回复
cloudblaze 2020-04-13
能否把你的代码截个图或贴出来,谢谢哈。可能没有明白你说的意思。
  • 打赏
  • 举报
回复
sdghchj 2020-04-12
引用 2 楼 cloudblaze 的回复:
好像还是不可以,如果按照你这么改,会有编译时错误,不能访问私有字段。
我有叫你删掉friend声明吗???
  • 打赏
  • 举报
回复
cloudblaze 2020-04-12
好像还是不可以,如果按照你这么改,会有编译时错误,不能访问私有字段。
  • 打赏
  • 举报
回复
sdghchj 2020-03-28
1. 在内部类Node类外定义, 改成: template<typename T> std::ostream & operator<<(std::ostream & os, const T &node)

    template<typename T>
    std::ostream & operator<<(std::ostream & os, const T &node)
    {
        os << node._Data;
        return os;
    }

    template<typename T>
    std::ostream & operator<<(std::ostream & os, const List<T> & list)
    {
        os << list._Node;  //类型虽然是List<T>::Node,猜测猜测猜测在寻找函数匹配的时候不再管外部类List<T>的匹配。
        return os;
    }
2.在内部类Node类直接定义friend operator<<,可以编译通过:

        class Node
        {
        private:
            T _Data;
        public:
            friend std::ostream & operator<<(std::ostream & os, Node const &node){

            }
        };
  • 打赏
  • 举报
回复
相关推荐
发帖
C++ 语言

6.2w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
帖子事件
创建了帖子
2020-03-28 12:13
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下