模板 class 无法识别友元运算符
Template class not recognizing friend operator
所以我试图在模板中包含输入和输出运算符的两个友元声明 class 但每次我编译代码时它似乎都无法识别运算符。
这是我的头文件。
错误:严重性代码说明项目文件行抑制状态
错误 LNK2019 未解析的外部符号 "class std::basic_ostream & __cdecl operator<<(class std::basic_ostream &,class 屏幕<5,5> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@ @std@@AAV01@AAV?$Screen@$04$04@@@Z) 在函数 _main
中引用
似乎是链接错误。
Screen.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;
}
我注意到可以通过在 class 正文中包含友元声明和函数定义来解决问题,但我不想这样打点。
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&);
它似乎有效,但它给了我一个警告,让我知道没有找到运算符的函数定义,这甚至让我感到困惑 more.This 问题来自 c++ primer 5th edition chapter 16 problem 15
class里面的朋友应该是全专:
friend std::ostream& operator<< <>(std::ostream&, Screen&);
注意函数名后面的<>
。
friend std::ostream& operator<< <> (std::ostream&, Screen&);
--
没有这两个字符,友元声明就声明了一个非模板。也就是说,当你实例化Screen<3,5>
时,它会尝试找到一个具有这个签名
的函数
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>&);
在范围内(您的代码就是这种情况)。
所以我试图在模板中包含输入和输出运算符的两个友元声明 class 但每次我编译代码时它似乎都无法识别运算符。 这是我的头文件。
错误:严重性代码说明项目文件行抑制状态
错误 LNK2019 未解析的外部符号 "class std::basic_ostream
似乎是链接错误。
Screen.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;
}
我注意到可以通过在 class 正文中包含友元声明和函数定义来解决问题,但我不想这样打点。
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&);
它似乎有效,但它给了我一个警告,让我知道没有找到运算符的函数定义,这甚至让我感到困惑 more.This 问题来自 c++ primer 5th edition chapter 16 problem 15
class里面的朋友应该是全专:
friend std::ostream& operator<< <>(std::ostream&, Screen&);
注意函数名后面的<>
。
friend std::ostream& operator<< <> (std::ostream&, Screen&);
--
没有这两个字符,友元声明就声明了一个非模板。也就是说,当你实例化Screen<3,5>
时,它会尝试找到一个具有这个签名
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>&);
在范围内(您的代码就是这种情况)。