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 のサイズを変更してからクラッシュしないためです。したがって、アプリケーションのクラッシュを必要とするテスト ケースがない限り、この変更によってテスト ケースが壊れることはありません。
数え切れないほどの生産時間を節約し、数え切れないほどの未検出のバグから保護することは、作成者が持つ可能性のあるセマンティックなイデオロギーに絶対に勝ります。そこには。それは私の暴言です。どういたしまして。