[solved] g++ 模板类中的友元函数 链接出错

[answer]
将模板类中关于友元函数的声明更改为:
    template
    class GenericList
    {
    public:
        GenericList(int max);
        ~GenericList();
        int length() const;
        void add(ItemType new_item);
        bool full() const;
        void erase();
         template ItemType1> friend ostream& operator << (ostream& outs,const GenericList<ItemType1>& the_list);
    private:
        ItemType * item;
        int max_length;
        int current_length;
    };

[Question]
我在看 Walter Savitch的 《C++面向对象程序设计第7版》的模板类那一节时,例子程序运行出错。哪位大侠能帮我看看啊?
错误信息如下:
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# g++ main.cpp -o main.o
In file included from main.cpp:2:0:
genericlist.h:18:88: warning: friend declaration â€˜std::ostream& listsavitch::operator<<(std::ostream&, const listsavitch::GenericList&) declares a non-template function [-Wnon-template-friend]
genericlist.h:18:88: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) 
/tmp/ccFUMtfR.o: In function `main':
main.cpp:(.text+0x56): undefined reference to `listsavitch::operator<<(std::basic_ostream >&, listsavitch::GenericList const&)'
main.cpp:(.text+0xb8): undefined reference to `listsavitch::operator<<(std::basic_ostream >&, listsavitch::GenericList const&)'
collect2: ld returned 1 exit status

代码源文件如下:
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# ls
genericlist.cpp  genericlist.h  main.cpp
root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim genericlist.h
#ifndef GENERICLIST_H
#define GENERICLIST_H
#include 
using namespace std;

namespace listsavitch
{
    template
    class GenericList
    {
    public:
        GenericList(int max);
        ~GenericList();
        int length() const;
        void add(ItemType new_item);
        bool full() const;
        void erase();
         friend ostream& operator <<(ostream& outs,const GenericList& the_list);
    private:
        ItemType * item;
        int max_length;
        int current_length;
    };

}   //listsavitch
#endif //LIST_H

root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim genericlist.cpp
#ifndef GENERICLIST_CPP
#define GENERICLIST_CPP
#include 
#include 
#include "genericlist.h"

using namespace std;

namespace listsavitch
{
    //use cstdlib;
    template
    GenericList::GenericList(int max) : max_length(max),current_length(0)
    {
        item=new ItemType[max];
    }

    template
    GenericList::~GenericList()
    {
        delete [] item;
    }
    
    template
    int GenericList::length() const
    {
        return (current_length);
    }

    template
    void GenericList::add(ItemType new_item)
    {
        if(full())
        {
            cout << "Error: adding to a full list.\n";
            exit(1);
        }
        else
        {
            item[current_length]=new_item;
            current_length=current_length+1;
        }
    }

    template
    bool GenericList::full() const
    {
        return (current_length==max_length);
    }

    template
    void GenericList::erase()
    {
        current_length=0;
    }

    template
    ostream& operator <<(ostream& outs,const GenericList& the_list)
    {
        for(int i=0;i             outs << the_list.item[i] << endl;
        return outs;
    }

}
#endif

root@xiaoy-ProLiant:/home/xiaoy/sample/Class_Template# vim main.cpp
#include 
#include "genericlist.h"
#include "genericlist.cpp"
using namespace std;
using namespace listsavitch;

int main()
{
    GenericList first_list(2);
    first_list.add(1);
    first_list.add(2);
    cout << "first_list = \n"
        << first_list;

    GenericList second_list(10);
    second_list.add('A');
    second_list.add('B');
    second_list.add('C');
    cout << "second_list = \n"
        << second_list;
    return 0;
}

你可能感兴趣的:(c++/g++)