在命名空间内的类中使用带有运算符重载的字符串流时,“与‘operator>>’不匹配”

2024-05-04

我试图在命名空间内的类中重载 >> 运算符,但是一旦我尝试将它与字符串流一起使用,它就不起作用。这是我的代码的精炼版本:

#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;
}

不管怎样,非常感谢您的帮助!感谢您没有亲自给我提供解决方案;通过自己弄清楚来学习要好得多,即使我确实得到了一些帮助,为我指明了正确的方向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在命名空间内的类中使用带有运算符重载的字符串流时,“与‘operator>>’不匹配” 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐