cambunctious
cambunctious

Reputation: 9582

multi_array_view assignment without deep copy?

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.

Upvotes: 2

Views: 460

Answers (1)

sehe
sehe

Reputation: 393064

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.

Upvotes: 2

Related Questions