2

boost::multi_:array のコピー コンストラクターの実装を理解するのに問題があります。

次のことを試してみると

std::vector<double> a;
std::vector<double> b;
a.resize(12);
b.resize(10);
a=b;

すべてうまくいき、

しかし、私がしようとすると

boost::multi_array<double,1> a;
boost::multi_array<double,1> b;
a.resize(boost::extents[12]);
b.resize(boost::extents[10]);
a=b;

クラッシュします。

私は同じ動作を期待していましたが、ドキュメントには有用なものが見つかりませんでした.

誰にもアイデアはありますか?

よろしく

アワラブ

4

2 に答える 2

2

割り当てとboost::multi_array同じように機能するように見えます。つまり、2つの配列のサイズが一致している必要があります。std::valarray

ドキュメントによると:

配列タイプ、、、およびのそれぞれは、multi_arrayそれらのmulti_array_ref形状が一致する限り、他の任意の配列タイプから割り当てることができます。subarrayarray_view

于 2011-07-05T14:05:24.813 に答える
0

boost::multi_array 代入演算子のセマンティクスは腹立たしいほど悪く、開発者の時間をこのような答えを探すために無数の工数を浪費しています。笑えるほどの傲慢とでも言いましょうか。

multi_array.hpp 内の代入演算子を次のように修正できます。

  // replacement for arrogant boost::multi_array assignment semantics
  template <typename ConstMultiArray>
  multi_array& operator=(const ConstMultiArray& other) {
    // deallocate
    deallocate_space();
    base_ = 0;
    allocated_elements_ = 0;
    // copy members of const_multi_array_ref
    storage_ = other.storage_;
    extent_list_ = other.extent_list_;
    stride_list_ = other.stride_list_;
    index_base_list_ = other.index_base_list_;
    origin_offset_ = other.origin_offset_;
    directional_offset_ = other.directional_offset_;
    num_elements_ = other.num_elements_;
    // allocate
    allocator_ = other.allocator_;
    allocate_space();
    // iterator-based copy
    std::copy(other.begin(),other.end(),this->begin());
    return *this;
  }

  multi_array& operator=(const multi_array& other) {
    if (&other != this) {
      // deallocate
      deallocate_space();
      base_ = 0;
      allocated_elements_ = 0;
      // copy members of const_multi_array_ref
      storage_ = other.storage_;
      extent_list_ = other.extent_list_;
      stride_list_ = other.stride_list_;
      index_base_list_ = other.index_base_list_;
      origin_offset_ = other.origin_offset_;
      directional_offset_ = other.directional_offset_;
      num_elements_ = other.num_elements_;
      // allocate
      allocator_ = other.allocator_;
      allocate_space();
      // copy
      boost::detail::multi_array::copy_n(other.base_,other.num_elements(),base_);
    }
    return *this;
  }

この場合のブースト作成者の無関係な信念に反して、この種の修正は何も壊しません。何も壊れない理由は、元のライブラリの動作が、サイズが一致しない場合にアサーションでクラッシュすることであるのに対し、新しいコードは最初に multi_array のサイズを変更してからクラッシュしないためです。したがって、アプリケーションのクラッシュを必要とするテスト ケースがない限り、この変更によってテスト ケースが壊れることはありません。

数え切れないほどの生産時間を節約し、数え切れないほどの未検出のバグから保護することは、作成者が持つ可能性のあるセマンティックなイデオロギーに絶対に勝ります。そこには。それは私の暴言です。どういたしまして。

于 2015-06-02T07:35:31.493 に答える