C++重载运算符'>>'

4

我已经查看了很多不同的例子和解释,但没有一个真正回答了我所寻找的。我有三个类,每个类都有一个名为connect的方法:

class foo { ... }
void foo::connect(bar br) { ... }

class bar { ... }
bar& bar::connect(baz bz) { ... }

class baz { ... }
baz& baz::connect() { ... }

在我的主类中,我像这样“连接”它们:
foo.connect(bar);
bar.connect(baz);
baz.connect();

或者:

foo.connect( bar.connect( baz.connect() ) );

我知道这个解释比较简略,如果需要的话,我可以更好地解释一下。

因此,我尝试重载运算符'>>',以便在主函数中获得以下内容:

foo >> bar >> baz;

对于第一个运营商,它可以正常工作,所以如果我只是按照以下步骤操作,它就可以正常工作:

foo >> bar.connect(baz.connect);

但是,当我设置另一个'>>'操作符时,g++会返回以下错误:

error: no match for ‘operator>>’ in ‘operator>>((* & foo), (* & bar)) >> baz.baz::connect()’

我认为我没有正确地重载了运算符'>>':

bar& operator>> (bar &br, baz &bz)
{
  ...
}

感谢您的帮助 :)

请注意,不建议在非流和非位移操作中使用 >> - user1781290
没错,但是我使用运算符“>”时遇到了更多问题,所以我开始尝试这个,看起来它似乎可以工作。不管怎样,也许这不是一个好主意。谢谢! - makeMonday
3个回答

5

运算符并不神奇:它们只是用一种有趣的方式拼写的函数。也就是说,你的语句

foo >> bar >> baz;

实际上只是调用[或尝试调用]
operator>> (operator>> (foo, bar), baz);

也就是说,你需要使用运算符。
bar& operator>> (foo& f, bar& b) {
    f.connect(b);
    return b;
}
bar& operator>> (bar& b0, baz& b1) {
    return b0.connect(b1);
}

请注意,最后一个connect()无法使用operator>>()进行操作,因为该操作符始终需要两个参数。

你说的关于 operator>> 所做的调用是正确的。我以前没有想过这种方式,现在我看到这对我来说有点成问题。按照你提出的方式去做应该完全可行,但问题是我不能那样做。不管怎样,我会尝试一下并让你知道结果。谢谢! - makeMonday

2
尽管您没有表现出来,但证据表明您的其他运营商存在问题。看起来是这样的:
foo& operator>>(foo&, bar&) { ... }

但为了使其正常工作:

foo >> bar >> baz;

你可能希望foo >> bar返回bar而不是foo,这样下一次调用该函数时就会是这个函数:
??? operator>>(bar&, baz&) { ... }

为了保持一致性,这可能应该返回baz&,尽管在这种情况下并不是绝对必要的。
您目前的写法(因为foo >> bar会返回foo),第二个operator>>试图调用一个不存在的函数:
??? operator>>(foo&, baz&) { ... }

我没有那个第一个运算符,但是我发现你关于 foo >> bar 返回 'bar' 而不是 'void' 很有趣。在这种情况下,我会尝试这样做。谢谢! - makeMonday

2
你的重载运算符以 bar& 作为左操作数,以 baz& 作为右操作数,但你的示例代码如下:
foo >> bar.connect(baz.connect);

左操作数为foo&,右操作数为bar&。你是否还需要定义另一个版本的operator>>

同时请注意,引用你的样例代码,以下代码:

foo.connect(bar);
bar.connect(baz);
baz.connect();

这并同于这个:
foo.connect( bar.connect( baz.connect() ) );

操作顺序不同;在第二个示例中,baz.connect()首先运行,然后是bar.connect()等。这与第一个示例相反。这可能对您的应用程序没有影响,但这是需要考虑的事情。


我已经为每个类重载了operator>>,以便它们返回相同类的对象:foo.connect(bar); // 返回void bar.connect(baz); // 返回bar& baz.connect(); // 返回baz&这是有意为之的,这样我就可以使用operator>>创建这种“符号”,所以foo >> bar.connect(baz.connect());实际上是foo >> bar_object_returned; 顺便说一下,这个方法很好用。问题在于当我有foo >> bar >> baz时,它会说我实际上正在执行(foo >> bar) >> baz,但它并没有抱怨(foo >> bar)返回void。它只是这样做。 - makeMonday
顺便说一下,我完全同意这两种符号之间的区别,直到现在我才意识到这一点。谢谢! - makeMonday

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接