Итак, я пытаюсь включить два объявления друзей для оператора ввода и вывода в класс шаблона, но каждый раз, когда я компилирую код, кажется, что он не распознает оператор. вот мой файл заголовка.
ОШИБКА: Код серьезности Описание Ошибка состояния подавления строки файла проекта LNK2019 неразрешенный внешний символ "класс std :: basic_ostream & __cdecl operator << (класс std :: basic_ostream &, class Screen <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;
}
I заметил, что проблему можно решить, включив объявление друга и определение функции в тело класса, но я не хочу расставлять точки таким образом.
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&);
, кажется, что он работает, но он дает мне предупреждение, дающее мне знать, что определение функции для оператора не найдено, и это меня еще больше смутило. Эта проблема взята из п. п. С ++, глава 16, проблема 15