Конструктор ускоренного копирования нескольких массивов - PullRequest
2 голосов
/ 05 июля 2011

У меня проблема с пониманием реализации конструктора копирования 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 ]

2 голосов
/ 05 июля 2011

Похоже, что boost::multi_array работает так же, как std::valarray в отношении назначения, то есть размер двух массивов должен совпадать.

Согласно документации :

Каждый из типов массивов multi_array, multi_array_ref, subarray и array_view может быть назначен из любого другого, если их формы совпадают.

0 голосов
/ 02 июня 2015

Семантика операторов присваивания boost :: multi_array невероятно плоха, тратя бесчисленное количество человеко-часов времени разработчиков на поиск ответов, подобных этому, и, что еще хуже, представление lord знает, сколько скрытых ошибок, которые остались незамеченными в проектах, во всеммир, по причинам, которые я мог бы лучше всего описать как смехотворное высокомерие.

Вы можете исправить операторы присвоения внутри 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, а затем не сбой.Таким образом, если у вас нет тестовых случаев, требующих сбоя приложения, никакие тестовые примеры не могут быть нарушены этим изменением.

Экономия бесчисленных часов производительности и защита от бесчисленных необнаруженных ошибок абсолютно превосходит любойсемантические идеологии у авторов могут быть.Там.Это моя напыщенная речь.Не за что.

...