4

It seems strange but this simple code works with int instead of T, and does not work with template T.

template <typename T>
class Polynomial {

public:
    Polynomial (T i) {}
    Polynomial& operator+= (const Polynomial& rhs) {
        return *this;
    }
};

template <typename T>
const Polynomial<T> operator+ (Polynomial<T> lhs_copy, const Polynomial<T>& rhs) {
    return lhs_copy += rhs;
}

Polynomial<int> x (1), y = x + 2; // no match for 'operator+' in 'x + 2'
Cœur
  • 37,241
  • 25
  • 195
  • 267
se0808
  • 556
  • 3
  • 18
  • 1
    The semicolons (`;`) after definition of ctor and `operator+=` aren't needed, delete them. – GingerPlusPlus Oct 24 '14 at 17:10
  • @GingerPlusPlus: there is "Polynomial lhs" by value. – se0808 Oct 24 '14 at 17:12
  • 2
    @se0808: You're right, sorry. Usually objects get passed using const reference, I missed that your code makes the copy. Anyway, that's interesting idea - you don't have to create temporary, you can let the compiler do this. – GingerPlusPlus Oct 24 '14 at 17:14

1 Answers1

7

Implicit conversion don't apply during template argument deduction, you might render your function friend(so that the type is known):

template <typename T>
class Polynomial {
public:
    Polynomial (T i) {};
    Polynomial& operator+= (const Polynomial& rhs) { return *this; };

    friend Polynomial operator+ (Polynomial lhs, const Polynomial& rhs) {
        return lhs+=rhs;
    }
};

Also related: C++ addition overload ambiguity

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • Interesting solution, I didn't know that would work. But you don't want to be returning a reference to a local variable. – Mike Seymour Oct 24 '14 at 17:11
  • I agree, OP's code is hopefully just a placeholder for something else since is not doing anything useful anyway. I'll make this clear. – Marco A. Oct 24 '14 at 17:13
  • The `rhs` is constructed with `2` for `y = x + 2` but why it isn't the case with `lhs` for `y=2+x` ? – P0W Oct 24 '14 at 17:16
  • 1
    It's not a placeholder; the function body should still be `return lhs += rhs;`, giving the correct implemention of `+` in terms of `+=` as long as `lhs` is passed and returned by value. – Mike Seymour Oct 24 '14 at 17:19
  • @MikeSeymour assuming I'm reading your comment correctly (and since I'm not aware of what OP intended to do), returning + in terms of += is going to modify the left-hand variable. That's probably not what OP wanted (or did he?) – Marco A. Oct 24 '14 at 17:22
  • @MarcoA.: The left-hand operand is passed by value, so it only modifies the local copy of it. (An alternative, more verbose, option is to pass by `const` reference and explicitly make a local copy. While clearer, it's not so good these days since it inhibits move semantics.) – Mike Seymour Oct 24 '14 at 17:26
  • That's right, I'm probably getting tired for today. I missed it. Thanks – Marco A. Oct 24 '14 at 17:28
  • @P0W: It is the case for `2+x`. If either operand is `Polynomial`, then this operator will be found by ADL, and the other operand converted if necessary. – Mike Seymour Oct 24 '14 at 17:32
  • 1
    @P0W: That's because your left-hand operand is a reference. It should be a value (as should the return type). – Mike Seymour Oct 24 '14 at 17:35