提升MultiArray复制构造函数

时间:2011-07-05 13:24:09

标签: c++ boost copy-constructor boost-multi-array

我在理解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;

我崩溃了。

我期待相同的行为,但我在文档中也找不到任何有用的东西。

有没有人有想法?

此致

awallrab

2 个答案:

答案 0 :(得分:2)

看起来boost::multi_arraystd::valarray的工作方式类似,就像分配一样,即2个数组的大小必须匹配。

根据the documentation

  

每个数组类型multi_arraymulti_array_refsubarrayarray_view都可以从其他任何数组中分配,只要它们的形状匹配。

答案 1 :(得分: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的大小,然后< em>不崩溃。因此,除非您有需要应用程序崩溃的测试用例,否则此更改不会破坏任何测试用例。

节省无数小时的工作效率并防范无数未检测到的错误绝对胜过作者可能具有的任何语义意识形态。那里。那是我的咆哮。不客气。