6

For example, the assignment operators for std::slice_array:

void operator=(const valarray<T>&) const; //#1
void operator=(const T&) const; //#2
const slice_array& operator=(const slice_array&) const; //#3

#1 and #2 return void, but #3 returns const slice_array&.

It prohibits some code, such as:

std::valarray<int> va{1, 2, 3, 4, 5, 6};
va[std::slice(3, 2, 2)] = va[std::slice(0, 2, 2)] = va[0];

Why?

1 Answers1

2

While returning a reference from operator= is the common and reasonable way for implementations, keep in mind that valarray is a rarely used and an unsupported library. See C++ valarray vs. vector for more detailed answers on this topic.

From one of the answers:

ISTR that the main reason it wasn't removed from the standard is that nobody took the time to evaluate the issue thoroughly and write a proposal to remove it.

Even before going into debates about opinions, there are bugs in the current implementation. See assigning to gslice_array gives runtime error for instance.

Burak
  • 2,251
  • 1
  • 16
  • 33
  • 1
    There must be a reason for the assignment operator to return `void`, you doesn't answer my question. Also, I think it's a great tool for optimizing performance. – Blackteahamburger Oct 15 '22 at 12:18
  • 1
    @Blackteahamburger Why not void? You are calling the assignment operator of a `slice_array`. The common return value should have been the `slice_array` itself, which is already assigned by some values. In order for your example to work correctly, the return value should have been `const T&` or `const valarray&`. While yours is not a bad idea, it is opinion based and is against common expectation. – Burak Oct 16 '22 at 10:05
  • What's the problem? For example, the assignment operators of another proxy class `std::bitset::reference` are `reference& operator=( bool x ) noexcept;` and `reference& operator=( const reference& x ) noexcept;`. – Blackteahamburger Oct 16 '22 at 11:23
  • @Blackteahamburger `bitset::reference` has implicit cast to `bool`. To get the same effect, `slice_array` should have an implicit cast to `valarray` which means an invisible costly copy operation. – Burak Oct 16 '22 at 13:36
  • I don't understand why the conversion is needed, the returned `slice_array` itself can be used for assignment to other `slice_array`s or `valarray`s, which is also the purpose of returning itself. – Blackteahamburger Oct 22 '22 at 07:25
  • @Blackteahamburger `slice_array::operator=(slice_array)` is not implemented. I think the standards committee just did not care. They would need to implement all subscript operators for all helper classes (`slice_array`, `gslice_array`, `indirect_array`, `mask_array`) with a gain of practically nothing. You can add one more line to achieve what you want anyway. – Burak Oct 23 '22 at 05:50
  • But there is `const slice_array& operator=(const slice_array&) const;` The assignment operators are used to assign to the referenced elements, not to itself. – Blackteahamburger Oct 23 '22 at 11:19
  • @Blackteahamburger You are right here. As long as the subscripts are `slice_array`, the chained assignment works too. If the assignment operator for other helper classes were implemented, returning `*this` would make sense. But as is, making `slice = slice = val` work and `gslice = slice = val` an error brings confusion. Why did the committe decided not to implement them? Well, I agree with you here that they should be implemented. Which makes us come to the beginning of this answer :) – Burak Oct 23 '22 at 16:54
  • @Blackteahamburger Sorry about my erroneous `slice_array::operator=(slice_array)` comment. It all boils down to *"Why `slice_array::operator=(gslice_array)` and similar functions are not implemented?"*. Your questions are pretty good by the way. Keep it up! – Burak Oct 23 '22 at 17:13
  • However, `slice = gslice` doesn't work either, because they are different kinds of slices. So maybe it's just one of the odd designs of the committee, no good reason. I'm going to propose a fix & extension to `valarray` instead of continuing to ask why here. – Blackteahamburger Oct 29 '22 at 00:56