c++ - 在命名空间内的类中使用带有运算符重载的字符串流时“不匹配'运算符>>'”
问题描述
我试图在命名空间内的一个类中重载 >> 运算符,但是一旦我尝试将它与字符串流一起使用,它就不起作用。这是我的代码的提炼版本:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
namespace Foo {
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Bar& t);
};
}
inline istream& operator >>(istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
这是错误:
main.cpp:22:22: error: no match for ‘operator>>’ (operand types are ‘std::stringstream {aka std::__cxx11::basic_stringstream<char>}’ and ‘Foo::Bar’)
问题是这些其他的工作方式:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
namespace Foo {
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
};
}
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Bar {
public:
string str;
friend istream& operator >>(istream& in, Bar& t);
};
inline istream& operator >>(istream& in, Bar& t) {
in >> t.str;
return in;
}
int main() {
Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
问题是,我不知道为什么第一种方法应该是错误的。如果有帮助,我在 linux 上使用 g++ 编译器。有人可以帮我理解发生了什么吗?
解决方案
感谢 Sam Varshavchik 的提示(在上面的评论中),我已经能够提出第一个版本的正确版本:
#include <iostream>
#include <string>
#include <sstream>
namespace Foo {
class Bar {
public:
std::string str;
friend std::istream& operator >>(std::istream& in, Bar& t);
};
std::istream& operator >>(std::istream& in, Bar& t);
}
std::istream& Foo::operator >>(std::istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
using namespace std;
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
关键是确保 operator>> 函数在同一范围内声明和定义。我仍然希望能够在命名空间大括号之外定义函数,因此我必须在命名空间内添加一个声明,以便编译器知道命名空间中应该有该函数。保持函数定义分开允许我将我的代码分成三个文件,main.cpp、foo.hpp 和 foo.cpp:
// main.cpp
#include <iostream>
#include <string>
#include <sstream>
#include "foo.hpp"
using namespace std;
int main() {
Foo::Bar foo;
stringstream("foo") >> foo;
cout << foo.str << endl;
return 0;
}
// foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
#include <string>
#include <iostream>
namespace Foo {
class Bar {
public:
std::string str;
friend std::istream& operator >>(std::istream& in, Bar& t);
};
std::istream& operator >>(std::istream& in, Bar& t);
}
#endif
// foo.cpp
#include "foo.hpp"
std::istream& Foo::operator >>(std::istream& in, Foo::Bar& t) {
in >> t.str;
return in;
}
无论如何,非常感谢您的帮助!感谢您没有亲自给我一个解决方案;通过自己弄清楚来学习会好得多,即使我确实得到了一些帮助,为我指明了正确的方向。
推荐阅读
- php - 如何直接从 url 将文件上传到 S3 存储桶
- javascript - 在javascript中运行动画函数后如何添加函数/元素动作?
- .net - 如何设置 Visual Studio Pack 默认发布而不是像发布按钮这样的当前模式
- python - 如何在 Android Studio 项目中添加 Python Selenium 脚本
- spring-boot - 在 Spring Boot 的 LDAP 身份验证中使用 sAMAccountName 而不是 userPrincipalName
- java - 二元运算符 '<=' , '+=' 的错误操作数类型
- jquery - 如何在 jQuery select2 远程选择框中设置默认选择值的排序?
- php - 如何确定一行中是否有 X 个时隙?
- sql - 比较 PostgreSQL 中的两列仅显示最高值
- c# - 我无法让 OnMouseOver() 注意到我的鼠标悬停在 c# (Unity) 中的按钮上