std::valarray::operator=(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

Okay bestie, you found the std::valarray::operator=(3) page from the C++ Standard Libary manual (yes, that spelling is what the header says, not me πŸ’…). This is all about replacing the contents of a numeric array, and there are eight overloads. Eight! Not me being dramatic β€” that's just the assignment operator being a whole main character.


🌸 NAME 🌸

std::valarray::operator= β€” and the one-line summary is also std::valarray::operator=. That's it. That's the name. Slay.

✨ Synopsis ✨

valarray<T>& operator=( const valarray<T>& other );            (1)
valarray<T>& operator=( valarray<T>&& other ) noexcept;        (2)
(since C++11)
valarray<T>& operator=( const T& val );                        (3)
valarray<T>& operator=( const std::slice_array<T>& other );    (4)
valarray<T>& operator=( const std::gslice_array<T>& other );   (5)
valarray<T>& operator=( const std::mask_array<T>& other );     (6)
valarray<T>& operator=( const std::indirect_array<T>& other ); (7)
valarray<T>& operator=( std::initializer_list<T> il );         (8)
(since C++11)

Replaces the contents of the numeric array. Lowkey the whole point.

Here's the overload tea, in order:

  1. Copy assignment operator (1). If size() != other.size(), first resizes *this as if by resize(other.size()). Each element of *this is assigned the value of the corresponding element of other.
  2. Move assignment operator (2, since C++11). Replaces the contents of *this with those of other. The value of other is unspecified after this operation. The complexity of this operation may be linear if T has non-trivial destructors, but is usually constant otherwise.
  3. Scalar fill (3). Replaces each value in *this with a copy of val.
  4. Generalized subscripting (4-7). Replaces the contents of *this with the result of a generalized subscripting operation. The behavior is undefined if size() does not equal the length of other or if any value on the left depends on the value on the right (e.g. v = v[v > 2]). That's undefined behavior, bestie β€” do not play with that.
  5. Initializer list (8, since C++11). Assigns the contents of initializer list il. Equivalent to *this = valarray(il).

πŸ’– Parameters πŸ’–

  • other β€” another numeric array (or a mask) to assign.
  • val β€” the value to initialize each element with.
  • il β€” initializer list to assign.

🫢 Return value 🫢

It returns *this. That's the whole section. Cute and to the point.

😭 Exceptions 😭

For overloads 1,3-8), it may throw implementation-defined exceptions.

πŸŽ€ Example πŸŽ€

Run this code, bestie:

// Run this code

#include <iomanip>
#include <iostream>
#include <valarray>

void print(const char* rem, const std::valarray<int>& v)
{
    std::cout << std::left << std::setw(36) << rem << std::right;
    for (int n : v)
        std::cout << std::setw(3) << n;
    std::cout << '\n';
}

int main()
{
    std::valarray<int> v1(3);
    v1 = -1; // (3) from a scalar
    print("assigned from scalar: ", v1);

    v1 = {1, 2, 3, 4, 5, 6}; // (8): from initializer list of different size
    print("assigned from initializer_list:", v1);

    std::valarray<int> v2(3);
    v2 = v1[std::slice(0, 3, 2)]; // (4): from slice array
    print("every 2nd element starting at pos 0:", v2);

    v2 = v1[v1 % 2 == 0]; // (6): from mask array
    print("values that are even:", v2);

    std::valarray<std::size_t> idx = {0, 1, 2, 4}; // index array
    v2.resize(4); // sizes must match when assigning from gen subscript
    v2 = v1[idx]; // (7): from indirect array
    print("values at positions 0, 1, 2, 4:", v2);
}

🌈 Output 🌈

assigned from scalar:                -1 -1 -1
assigned from initializer_list:       1  2  3  4  5  6
every 2nd element starting at pos 0:  1  3  5
values that are even:                 2  4  6
values at positions 0, 1, 2, 4:       1  2  3  5

πŸ‘‘ Defect reports πŸ‘‘

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • LWG 624, applied to C++98: the behaviors of overloads (4-7) were unclear if the length of other is not size(); correct behavior: the behaviors are undefined in this case.
  • LWG 630, applied to C++98: the behavior of the copy assignment operator was undefined if size() != other.size(); correct behavior: resizes *this first in this case.
  • LWG 2071, applied to C++11: the move assignment operator resized *this if size() != other.size(); correct behavior: not required to resize in this case.

Okay that's the whole page, bestie. Stay hydrated, don't depend on the right side while assigning the left, and remember: this was from http://cppreference.com, with the little date stamp 2024.06.10 and the page std::valarray::operator=(3). Mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from