C++ 链接不使用'的运算符;不要返回对象

C++ 链接不使用'的运算符;不要返回对象,c++,C++,我需要定义一个节点类,该类需要一个重载的'+'运算符函数,该函数返回两个节点的总和。 我很乐意这样做,但我忍不住想知道为什么它应该返回一个双精度的和,因此,这个操作符的链接将不再可能 我的意思是,node1+node2可以工作,但是,node1+node2+node3不能 如何利用返回双精度的重载“+”运算符实现5个节点的组合和? 编辑: 如果可以添加节点和双精度节点,则可以通过定义节点和双精度节点的添加来支持多个添加: class Node { public: friend dou

我需要定义一个节点类,该类需要一个重载的'+'运算符函数,该函数返回两个节点的总和。

我很乐意这样做,但我忍不住想知道为什么它应该返回一个双精度的和,因此,这个操作符的链接将不再可能

我的意思是,
node1+node2
可以工作,但是,
node1+node2+node3
不能

如何利用返回双精度的重载“+”运算符实现5个节点的组合和?

编辑:


如果可以添加节点和双精度节点,则可以通过定义节点和双精度节点的添加来支持多个添加:

class Node {
  public:
    friend double operator+(double a, Node &b);
    double operator+(double b) {
      // however you get the sum here
      // for example, if the sum is a field of the node:
      return this->weight + b;
    }
}
double operator+(double a, Node &b) { return b + a; }
注意,我们必须同时定义
Node+double
double+Node
,以支持
a+(b+c)
以及
(a+b)+c


编辑:为了响应您的编辑,我更新了代码。

如果您还实现了强制转换操作符,例如
操作符double()
,您将能够隐式强制转换链式添加的结果,并且以下操作应能起作用:

Node a(3.0);
Node b(7.0);
Node c(24.0);
double x = a + b + c;

有两种选择。要么使用“double+node”对您来说是有意义的,并且您理解这意味着什么,要么您不能从操作符返回double

我会详细说明的。没有C++中的TrimeTalk +(也没有任何其他语言我知道)。你的node1+node2+node3实际上是(node1+node2)+node3。为了便于参考,让我们对运算符p1和p2进行编号(左侧为p1,右侧为p2)

现在你必须决定哪个更有意义。特别是,在研究“节点”的语义时,执行“2.3+节点”有意义吗?如果是这样的话,只需定义一个接受一个节点和一个double的操作符+,然后使用它就可以了

更进一步地说,如果一个节点的值几乎不超过它的值,那么可以创建一个接受double的节点构造函数,从而创建从double到节点的隐式转换

另一种说法是“双+节点”毫无意义。也许一个节点有很多方面,它的价值只是其中之一。如果是这种情况,并且有某种有意义的方法可以“添加”两个节点,那么您需要运算符+返回一个节点。没办法

还有第三种选择。如果无法添加两个节点并获得第三个节点,但使用“双+节点”也没有意义,那么您需要一个代理类

class node {
private:
  class node_value {
  public:
    double value;
    operator double() { return value; }
  }

  node_value operator+( const node &rhs );
  node_value operator+( const node_value &rhs );
};

运算符+for node返回一个代理类,该类可以隐式转换为double。它为主加法定义运算符+的第一种形式,为链式加法定义运算符+的第二种形式。当然,您还需要在类之外定义交换参数操作符。

对于链接,您可以覆盖
节点的
操作符double
,如

struct Node {
   double operator+(const Node & n) const {
       return n.val + val;
   }

   Node(double val) : val(val) {}

   operator double() {
      return val;
   }

   double val;
};
然后你可以做:

Node n1(1);
Node n2(2);
Node n3(3);
std::cout << n1 + n2 + n3 << endl; // 6

请参见操作:

运算符+()的返回类型是什么?请共享您的代码,以便尝试使用node1+(双精度),这是您的实现所不希望的。您的分配是错误的,您只需输入错误的代码即可完成错误的分配。你也可以交上正确的代码并在分数上丢分。是的,这个选项听起来很有趣。如何实现cast操作符?@MattMilna
Node::operator double(){return this->weight;}
,或者更一般地说,
Node::operator TYPE()
;不是成员,特别是因为它与后者一样是非法的。你完全正确,WhozCraig,它现在应该被修复。代理选项是-IMHO-最优雅的,但是你当前的代码将添加最左边的两个
节点
产生一个
节点
值,该值不能添加到下一个
节点
。您可以使用
node\u value::operator+(const node&rhs)
来解决这个问题。您确实有
节点值操作符+(const节点值&rhs)但是它需要在右边的
节点\u值
s,而…我在post code注释中提到了这一点。为了可读性,我省略了一些实现工作。。。“交换参数运算符”。。。那也行。干杯
Node n1(1);
Node n2(2);
Node n3(3);
std::cout << n1 + n2 + n3 << endl; // 6
struct NodeBetter {
  // Notice the return Type NodeBetter 
  NodeBetter operator+(const NodeBetter & n) const {
       return NodeBetter(n.val + val);
   }
   double val;
   NodeBetter(double val) : val(val) {}
};

 // in main()
 NodeBetter n1(1);
 NodeBetter n2(2);
 NodeBetter n3(3);
 std::cout << (n1 + n2 + n3).val << endl; // again 6. :)