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;
}
在这种情况下,与 boost 作者的不相关信念相反,这种修复不会破坏任何东西。它不会破坏任何东西的原因是,如果大小不匹配,原始库的行为是通过断言直接崩溃,而新代码将首先调整 multi_array 的大小,然后不会崩溃。因此,除非您有需要应用程序崩溃的测试用例,否则此更改不可能破坏任何测试用例。
节省无数小时的生产力并防止无数未被发现的错误绝对胜过作者可能拥有的任何语义意识形态。那里。那是我的吐槽。别客气。