2

How can I reassign a boost multi_array_view to point to a different part of a multi_array? I don't want a deep copy.

boost::multi_array<int, 2> a(...);
array_view b = a[indices[index_range(0, 5)][index_range()]];
array_view c = a[indices[index_range(0, 10)][index_range()]];
b = c; // don't work

Boost source:

template <typename ConstMultiArray>
multi_array_ref& operator=(const ConstMultiArray& other) {
    function_requires< 
      multi_array_concepts::
      ConstMultiArrayConcept<ConstMultiArray,NumDims> >();

    // make sure the dimensions agree
    BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
    BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
                            this->shape()));
    // iterator-based copy
    std::copy(other.begin(),other.end(),this->begin());
    return *this;
}

Update: I ended up changing the approach in my program to keep a reference to the indices object created by boost::indices[...]. Then I can use that object to create a new array_view at any time.

1 Answer 1

2

Looks like multi_array_ref models a C++ reference closely:

  • it's not re-seatable
  • it's semantically an alias for the object it is "bound to"

Somewhat surprisingly, though, the same appears not to be the case for const_multi_array_ref. Note these documentation quotes:

All of the non-const array types in this library provide assignment operatorsoperator=(). Each of the array types multi_array, multi_array_ref, subarray, and array_view can be assigned from any of the others, so long as their shapes match. The const variants, const_multi_array_ref, const_subarray, and const_array_view, can be the source of a copy to an array with matching shape. Assignment results in a deep (element by element) copy of the data contained within an array.

This talks about assigning to a mutable array (view).

However:

Effects. This constructs a shallow copy of x.

Approaches

Perhaps you can use const_multi_array_ref instead.

Otherwise you should probably look to "break" the bind of un-reseatable references in exactly the same way we do it for C++ references: std::reference_wrapper<> or similar indirection.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, this is helpful. A multi_array_ref is only good for referencing an entire multi_array, not a view into part of the multi_array, correct?
Also, if I have a function that returns an array_view, do I need to wrap it in a reference_wrapper to avoid a deep copy?
I just realized that it doesn't make much sense to return a reference_wrapper. I guess I have to put it on the heap.
Yup. None of this is special for m-a-r. Is the exact same for c++ references. You can return reference_wrapper just fine. Just don't use it to return a reference to a local. Also m-a-r can be used to refer to any contiguous array, not just a full boost::multi_array
I wrote a library that supports subarray “pointer” reseating gitlab.com/correaa/boost-multi#pointer-to-subarray

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.