C++ 重载 >> 运算符基于 >> 的哪一侧具有不同的交互

C++ overload >> operator with different interaction based on which side of >>

我想知道是否可以用这种方式重载 C++ >> 运算符

Account& operator>> (double left, Account &right)
{
    right.deposit(left);
    return right;
}

Account& operator>> (Account &left, double right)
{
    left.withdraw(right);
    return left;
}

我想知道 >> 运算符是否具有此功能 所以我可以做这样的事情

account1 >> 200 >> account2

从第一个账户中取出200,然后存入第二个账户。

如上所述,由于以下简单原因,这将不起作用:

account1 >> 200 ...

当它被评估时,它最终会调用以下重载:

Account& operator>> (Account &left, double right)

请注意此重载 return 是一个 Account &。那是在那里白纸黑字宣布的。让我们继续:

... >> account2

现在,这个 operator>> 的左侧现在是一个 Account &,什么是重载 returned。它不再是 double。它需要是 double 才能让另一个超载收拾残局,并将其带回家。这就是重载运算符在 C++ 中的工作方式。

最简单的解决方案可能是 return 来自第一个重载的双精度值:

double operator>> (Account &left, double right)
{
    left.withdraw(right);
    return right;
}

现在这个表达式的结果是一个 double 值,这将更容易让另一个重载 operator>> 出现。

正如所指出的,在这两种情况下,您的 operator>>() returns 和 Account&,即您不能按照指示链接运算符。不过,您可以单独使用它们。然而,这似乎不是故意的。

可以 通过从 operator>> (Account& account, double amount) 返回类似 Withdraw(account, amount) 实体的内容并让第二个运算符成为 operator>> (Withdraw const& withdraw, Account&) 来实现您的有效目标。然后第二个操作员将触发交易。技术上可行,但我不相信这是可行的方法。

#include <utility>

struct Account {
    double withdraw(double amount) { return amount; }
    double deposit(double amount) { return amount; }
};
struct Withdraw {
    Account& account;
    double   amount;
    double do_it() && { return account.withdraw(amount); }
};

void operator>> (Withdraw && left, Account &right)
{
    right.deposit(std::move(left).do_it());
}

Withdraw operator>> (Account &left, double right)
{
    return Withdraw{left, right};
}

int main() {
    Account a1, a2;
    a1 >> 200 >> a2;
}

我不太确定这种方法是否可取。我想我会被代码弄糊涂,最好使用被命名的操作。然而,可能构建一个最终作为事务执行的操作对象,结合多个单独的操作仍然是合理的。