3

While implementing expression templates for a vector/array type, I inevitably came to the point where I need to provide operator +=.

Using the 'default' expression template scheme gives unintuitive results. The epxression a += b doesn't return the result of the computation but rather a reference to the left operand which by the means of an operator side effect is increased by the value b. If operator+=() now returns an expression template rather than immediately computing the result, a += b; will have no effect which would probably be rather surprising when using this scheme.

Is there any sophisticated way to handle compound assignment operators and/or side effects in the context of expression templates?

I can think of three possibilites right now:

  1. Use default expression templates and document that the expression template has to be evaluated (by whatever means are provided).

  2. Use special expression templates which have a destructor that performs side-effect computations if necessary.

  3. Provide compound assignment operators that do not use expression templates at all but rather immediately perform side effect computations.

I'm inclined towards using 3 because the other two have their respecitve downsides. While those for 1 are probably rather obvious, 2 has the problem that the construction of the expression template would have to ensure that the actual computation of the expression side effect does not throw if the destructor noexcept shall be maintained. This might in practice be problematic.

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
  • Still, `+=` **is** an assigment which has to be evaluated. Since, solution #1 would not evaluate it, #2 is not feasible, and #3 is not your intention, I would go with a fourth solution, **not** implementing `operator+=()` - it has the quasi - identical form of `a = b + c`. – Steeve Nov 16 '16 at 10:12
  • @Steeve: That's only true if you have access to/implemented `operator=`. If you do not, you'd want to have the compound operators. (I'm implementing expression templates for a project using `std::vector` with some very basic operator overloads. Thus, I'll have to (at least partially) make up for the lack of `operator=(my_expression_template<...>&&)`. – Pixelchemist Nov 16 '16 at 10:51
  • If you can't (why?) override `operator=()` then when is the expression going to be evaluated? In this case #3 is your only viable option in my opinion. – Steeve Nov 16 '16 at 11:42
  • @Steeve: Mainly because I can't touch `std::vector::operator=()`. The evaluation point is either user-requested via `result(...)`, `assign(...)` or performed via implicit conversion operator. (Unfortunately, each expression template will generate one temporary to be move assigned in case of `auto a = result(b + c)` and `vector a = b + c`.) I tend to agree about prefering *3*. – Pixelchemist Nov 16 '16 at 12:04
  • Isn't subclassing `std::vector` an option? – Steeve Nov 16 '16 at 12:37
  • @Steeve: The code using `std::vector` is already there. I just want to provide drop-in replacements for the operator functions (with some slight modifications where necessary). – Pixelchemist Nov 16 '16 at 12:58
  • I would still skip overloading `+=` operators and the like, true, you can not override assignment, but you have the alternative `result(...)` and `assign(...)` functions. In this case, `a += b` would be written in the form `a = result(a + b)`. – Steeve Nov 16 '16 at 13:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128265/discussion-between-pixelchemist-and-steeve). – Pixelchemist Nov 16 '16 at 13:35

0 Answers0