1

Here is my code:

#include <iostream>
#include <memory>
#include <vector>

class var {
private:
    double value_;
    std::shared_ptr<var> left_;
    std::shared_ptr<var> right_;

public:
    var(const double& v) : value_(v){};

    friend var operator+(const var& l, const var& r) {
        var result(l.value_ + r.value_);
        left_ = std::make_shared<var>(l.value_);
        right_ = std::make_shared<var>(r.value_);
        return result;
    }

    friend std::ostream& operator<<(std::ostream& os, const var& var) {
        os << var.value_;
        return os;
    }
};

int main() { var a(1); }

The error I am getting is as follows:

test.cpp: In function ‘var operator+(const var&, const var&)’:
test.cpp:17:9: error: invalid use of non-static data member ‘var::r_’
   17 |         r_.push_back(std::make_shared<var>(l.value_));
      |         ^~
test.cpp:10:39: note: declared here
   10 |     std::vector<std::shared_ptr<var>> r_;
      |                                       ^~

I am struggling to understand why I am getting the error in the title.
Is there a workaround?

9
  • 2
    left_ = ... and right_ = ... should be result.left_ = ... and result.right_ = .... You just forgot to name the instance whose members you want to assign. The error message should be pretty clear. left_ and right_ are members, and they aren't static so you need to access them via an instance. Commented Dec 27, 2022 at 14:11
  • 3
    The error message and the code doesn't match. Please make sure that you create a proper minimal reproducible example to show us, and then copy-paste (as text) the full and complete build log from that exact example. Commented Dec 27, 2022 at 14:14
  • 4
    There is no variable called r_ or any invocation of push_back in the code you have posted. Therefore any attempt at answering your question is speculation.
    – john
    Commented Dec 27, 2022 at 14:16
  • 1
    The usual approach to this sort of problem is to define operator+= as a member, which modifies the object that it's applied to. Then implement operator+ by creating a result object with a copy of one of the values, and adding the other value to it with +=. Voila: no friend declarations! Commented Dec 27, 2022 at 14:33
  • 2
    Having now actually looked at what the operator+ does, it doesn't seem that += makes sense. I provided generic advice for arithmetic types; this isn't one. Commented Dec 27, 2022 at 16:10

1 Answer 1

1

Your friend var operator+ is not a member of the class.
In order to access data members it should specify the instance.

Therefore change:

  left_ = std::make_shared<var>(l.value_);
  right_ = std::make_shared<var>(r.value_);

To:

//vvvvvvv---------------------------------------
  result.left_ = std::make_shared<var>(l.value_);
  result.right_ = std::make_shared<var>(r.value_);

Note:
As commented above by @PeteBecker: in the general arithmetic case a more efficient approach would be to implement operator+= as a member, and then implement operator+ in terms of it (create a copy of the 1st argument, use operator+ to add the 2nd to it and return it).
It is probably not relevant in this specific case, since operator+= doesn't make much sense.

2
  • damn it. such a rookie error. I have been away from c++ for too long.
    – HMPtwo
    Commented Dec 27, 2022 at 14:15
  • 1
    @HMPtwo -- the usual practice is to wait a day or so before accepting an answer; you might get a better one. Commented Dec 27, 2022 at 14:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.