【问题标题】:Template class not recognizing friend operator模板类不识别朋友运算符
【发布时间】:2020-11-01 22:53:56
【问题描述】:

因此,我尝试在模板类中包含输入和输出运算符的两个友元声明,但每次编译代码时,它似乎都无法识别该运算符。 这是我的头文件。

错误:严重性代码描述项目文件行抑制状态 错误 LNK2019 未解析的外部符号 "class std::basic_ostream & __cdecl operator &,class Screen & )" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Screen@$04$04@@@Z) 在函数_main中引用

似乎是链接错误。

屏幕.h

#include<string>
#include<iostream>
template<std::string::size_type, std::string::size_type>
class Screen;

template<std::string::size_type w, std::string::size_type h>
std::ostream& operator<<(std::ostream&,Screen<w, h>&);


template<std::string::size_type w,std::string::size_type h> 
class Screen{

    friend std::ostream& operator<<(std::ostream&, Screen&);
public:
    Screen()=default;
    Screen(const char str=' '):content(w*h,str){}

    Screen& set(char);
    Screen& set(std::string::size_type,std::string::size_type,char);
    char get() const {return content[cursor];}
    inline char get(std::string::size_type,std::string::size_type)const;

    Screen& move(std::string::size_type,std::string::size_type);
    Screen& display(std::ostream& os) { os<<content;  return *this; }



private:
    //void do_display(std::ostream& os) const { os << content; }
    std::string::size_type cursor=0;
    std::string content;
};
//MEMBER FUNCTIONS
template<std::string::size_type w,std::string::size_type h>
inline Screen<w,h>& Screen<w,h>::set(char c){
    content[cursor] =c;
    return *this;
}

template<std::string::size_type w,std::string::size_type h>
inline Screen<w,h>& Screen<w,h>::set(std::string::size_type r,std::string::size_type col,char ch){
    content[r*w+col]=ch;
    return *this;
}

template<std::string::size_type w,std::string::size_type h>
 inline Screen<w,h>& Screen<w,h>::move(std::string::size_type r,std::string::size_type c){
    cursor = r + w + c;
    return *this;
}

template<std::string::size_type w,std::string::size_type h>
inline char Screen<w,h>::get(std::string::size_type r,std::string::size_type c)const{
    return content[r*w+c];
}

//OS OPERATOR

template<std::string::size_type w, std::string::size_type h>
std::ostream& operator<<(std::ostream& os, Screen<w, h>& item) {
    os << item.content;
    return os;
}

这是我的主要 cpp 文件

main.cpp

#include"Screen.h"
#include<string>
#include<iostream>

using std::cout; using std::endl;
using std::string;

int main(){
    Screen<5,5> myScreen('X');
    myScreen.move(4, 0).set('#').display(cout);
    cout << endl;
    myScreen.display(cout);
    cout << endl;
    cout << myScreen << endl;
}

我注意到可以通过在类主体中包含朋友声明和函数定义来解决问题,但我不想这样添加。

public:
... other code

template<std::string::size_type w, std::string::size_type h>
friend std::ostream& operator<<(std::ostream& os, Screen<w, h>& item) {
    os << item.content;
    return os;
}

这让我很困惑,我试图理解为什么它会以这种方式工作而不是其他方式,而且我还注意到当我包含这样的朋友声明时

    friend std::ostream& operator<<<w,h>(std::ostream&, Screen&);

它似乎有效,但它给了我一个警告,让我知道找不到运算符的函数定义,这让我更加困惑。这个问题来自 c++ 入门第 5 版第 16 章第 15 题

【问题讨论】:

  • 请逐字复制并粘贴所有编译器消息。

标签: c++ class c++11 templates operator-overloading


【解决方案1】:
friend std::ostream& operator<< <> (std::ostream&, Screen&);
                                --

没有这两个字符,朋友声明声明一个非模板。也就是说,当你实例化Screen&lt;3,5&gt;时,它会尝试找到一个带有这个签名的函数

std::ostream& operator<< (std::ostream&, Screen<3,5>&);

而不是任何函数模板。没有这样的功能,所以这将失败。有效的声明将模板特化声明为友元,并且模板存在并且可以实例化,所以这里没有问题。

friend std::ostream& operator<< <w, h> (std::ostream&, Screen&);

也以同样的方式工作。 demo

这些friend 声明要求主模板声明

template<std::string::size_type w, std::string::size_type h>
std::ostream& operator<<(std::ostream&,Screen<w, h>&);

在范围内(您的代码就是这种情况)。

【讨论】:

    【解决方案2】:

    班里的朋友应该是全专业的:

    friend std::ostream& operator<< <>(std::ostream&, Screen&);
    

    注意函数名后面的&lt;&gt;

    template friends

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-27
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      相关资源
      最近更新 更多