0

attempting to pass an argument into overloaded method, NumericSet<T>* operator + (arma::Mat<T> obj1, int options) is this possible , if yes then what would the function call look like?

For example, how do I turn this

NumericSet<T> add(arma::Mat<T> mat, int option) 
{ 
    if (option == 1) 
    { 
        arma::Mat<T> sum = this->data + mat; 
        return new NumericSet<T>(sum); 
    } 
    else 
    { 
        this->data = this->data + mat; 
        return this; 
    } 
} 

into a proper operator+?

Thanks!

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • 1
    It's not possible. You can not pass "additional arguments" to the normal `+` operator, and your overloaded operators work just like the normal operators in that regard. – Some programmer dude Jan 19 '18 at 18:15
  • Also, having `operator+` return a pointer is almost guaranteed to be wrong; either you're leaking memory, mutating in-place when you should be returning a new object, using global state, or returning a pointer to invalid memory. `operator+` should be a non-member too (only `+=` should be a member). You should probably read [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/q/4421706/364696) – ShadowRanger Jan 19 '18 at 18:20
  • ill check it out thanks!! – jaideep seth Jan 19 '18 at 18:22
  • @Someprogrammerdude, that looks a lot like an answer. Could you please put it in the answer section so this can be removed from the Unanswered section? Thank you. – CodeMouse92 Jan 19 '18 at 18:24
  • NumericSet add(arma::Mat mat, int option) { if (option == 1) { arma::Mat sum = this->data + mat; return new NumericSet(sum); } else { this->data = this->data + mat; return this; } } – jaideep seth Jan 19 '18 at 18:28
  • i want to return a new NumericSet object, cant without return type being a NumericSet pointer, any work arounds? @ShadowRanger – jaideep seth Jan 19 '18 at 18:30
  • To salvage the above code, `return new NumericSet(sum);` -> `return NumericSet(sum);` and `return this;` -> `return *this;`. But first make absolutely certain `NumericSet` complies with [one of Rule of 0, 3, or 5](http://en.cppreference.com/w/cpp/language/rule_of_three) – user4581301 Jan 19 '18 at 18:35
  • 1
    @jaideepseth: Adding to user4581301, assuming the Rule of 0, 3 or 5 is followed, return by value should be cheap when it's returning a brand new object; with RVO/NRVO, any optimizing compiler should (usually) be able to move-construct into the caller or elide the construction entirely, so returning by value is just as efficient as returning a pointer to new memory, and avoids allocator overhead. – ShadowRanger Jan 19 '18 at 18:42
  • thanks for helping me improve my code!! – jaideep seth Jan 19 '18 at 18:43
  • I'm interested in how you imagine using one of these operators with additional arguments. Can you give an example of how you would call one of these operators? – François Andrieux Jan 19 '18 at 18:43
  • @FrançoisAndrieux I'm not certain enough to make an answer, but I think the asker's end goal of `option == 1` is `operator+` and the else is `operator+=` – user4581301 Jan 19 '18 at 18:46
  • naah i want a new object to be created iff the user chooses else the present object gets mutated...hence the "additional argument" – jaideep seth Jan 19 '18 at 18:47
  • That answers my question. You want two operators. `operator+` for non-mutating and `+=` for mutating. Note that `+` is sttunningly easy to implement based on `+=`. See the link @tobi303 provided for details. – user4581301 Jan 19 '18 at 18:48

1 Answers1

1

From looking at your comment code:

NumericSet<T> add(arma::Mat<T> mat, int option) {
    if (option == 1) {
        arma::Mat<T> sum = this->data + mat;
        return new NumericSet<T>(sum);
    } else {
        this->data = this->data + mat;
        return this;
    }
}

it looks like your real goal is to allow mutation in place or producing a new value. This is why there is a distinction between operator+= (for in-place operation) and operator+ (for not-in-place operation). Per the basic operator overloading idioms what you really want is to overload operator+= (as a member), then overload operator+ in terms of it (as a non-member), something along these lines:

template<typename T>
class NumericSet {
    ...
    NumericSet<T>& operator+=(const arma::Mat<T>& mat) {
        // Changed from this->data = this->data + mat
        // As a rule, += is always cheaper than +, so as long as data
        // is solely owned by this, mutating in place is likely to be much more efficient
        this->data += mat;
        return *this;
    }
}
template<typename T>
inline NumericSet<T> operator+(NumericSet<T> lhs, const arma::Mat<T>& rhs)
{
  lhs += rhs;
  return lhs;
}

Now you can just use + when you would have used option=1 and += when you would have used some other option value.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Note: Given `operator+` takes heterogeneous arguments, you may want to overload it in both directions, so you can do `mat + numset` and have it behave equivalently to `numset + mat`. – ShadowRanger Jan 19 '18 at 18:58