C2280: boost :: container :: map типа неопубликованного значения не может быть std :: move () 'd? - PullRequest
1 голос
/ 23 февраля 2020

У меня есть некопируемый класс Uncopyable, хранящийся в boost::container::map<K, Uncopyable>. Другой класс, Owner, имеет объект такой карты. Реализация Owner::Owner(Owner&&) требует перемещения map. Однако this->map = std::move(other.map) уступает C2280 в Boost's pair.hpp: «ссылка на удаленную функцию Uncopyable::Uncopyable(Uncopyable const&)».

Вот минимальный воспроизводимый пример. Несколько аспектов кода, таких как правило пяти, были опущены для краткости.

// Owner.h:
#include <boost/container/map.hpp>
class Key;
class Uncopyable;
class Owner {
private:
  boost::container::map<Key, Uncopyable> map = {};
public:
  Owner(Owner&&);
  Owner& operator=(Owner&&);
};
// Owner.cpp:
#include "Owner.h"
class Key {
};
class Uncopyable {
public:
  Uncopyable(Uncopyable&&) {
  }
  Uncopyable& operator=(Uncopyable&&) {
    return *this;
  }
  Uncopyable(Uncopyable const&)            = delete;
  Uncopyable& operator=(Uncopyable const&) = delete;
};
Owner::Owner(Owner&& other) {
  *this = std::move(other);
}
Owner& Owner::operator=(Owner&& other) {
  map = std::move(other.map);
  return *this;
}

Я забыл упомянуть, что map имеет Comparator для Key, переданного в качестве третьего параметр шаблона. Возможно исправлю пример позже.

В чем причина проблемы и как от нее избавиться? Это ошибка в Boost? Связана ли с этим тривиальность pair?

Если это важно, я использую C ++ 17 с (возможно) последней стабильной версией Boost и MSV C. Класс Uncopyable на самом деле std::variant<Copyable, Uncopyable>. map объявляется в .h с неполными типами, которые заканчиваются в. cpp, где размещены все определения.

...