我正在尝试使用fstream将包含自定义对象的STL地图保存到文件中。我正在使用<<和>>运算符重载。
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#define DELIM '/'
struct Point{
public:
int x, y;
};
//operator overloads for point
std::istream& operator>>(std::istream& is, Point& p){
std::string input;
std::getline(is, input, DELIM);
p.x = std::stoi(input);
std::getline(is, input, DELIM);
p.y = std::stoi(input);
return is;
}
std::ostream& operator<<(std::ostream& os, Point& p){
os << p.x << DELIM << p.y << DELIM;
return os;
}
//operator overloads for map<string, point>
std::istream& operator>>(std::istream& is, std::map<std::string, Point>& m){
std::string input;
std::getline(is, input, DELIM);
int map_size = std::stoi(input);
for(int i = 0; i < map_size; i++){
std::getline(is, input, DELIM);
Point p; is >> p;
m[input] = p;
}
return is;
}
std::ostream& operator<<(std::ostream& os, std::map<std::string, Point>& m){
os << m.size() << DELIM;
for(const auto& pair : m){
os << pair.first << DELIM;
os << pair.second;
}
return os;
}
int main(){
Point p1;
p1.x = 1; p1.y = 2;
Point p2;
p2.x = 100; p2.y = 150;
std::map<std::string, Point> map;
map["p1"] = p1;
map["p2"] = p2;
return 0;
}
当我尝试编译此文件时,出现以下错误:
test.cpp: In function 'std::ostream& operator<<(std::ostream&, std::map<std::basic_string<char>, Point>&)':
test.cpp:44:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
os << pair.second;
知道怎么解决这个问题吗?我之前使用模板遇到了这个问题,但是这里没有使用模板。关于SO的其他答案也涉及模板,并没有帮助我。为什么会发生这种情况的解释也将受到赞赏!
我用来编译的命令:(MinGW,gcc 4.8.1)
g++ test.cpp -o test -std=c++11 -Wall
完整的错误消息:
test.cpp: In function 'std::ostream& operator<<(std::ostream&, std::map<std::basic_string<char>, Point>&)':
test.cpp:44:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
os << pair.second;
^
In file included from c:\mingw\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\iostream:39:0,
from test.cpp:1:
c:\mingw\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Point]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
谢谢!
答案 0 :(得分:8)
下面
for(const auto& pair : m){
os << pair.first << DELIM;
os << pair.second;
}
pair
是常量,因此pair.second
也是const Point,它不能与Point&
的参数类型operator<<
匹配。
将Point
的{{1}}的参数类型更改为const引用:
operator<<
大多数情况下,传递给std::ostream& operator<<(std::ostream& os, const Point& p){
~~~~~
os << p.x << DELIM << p.y << DELIM;
return os;
}
的参数不会被更改,因此将operator<<
的类型声明为const&
是一种很好的做法。
operator<<
答案 1 :(得分:2)
传递给重载<<
运算符的参数应该是常量引用,而不是可变引用。