2

上下文:我有一个DLXMatrix具有某些属性的类,这些属性是某个名为Header. 每个都Header持有一些指向Header同一向量元素的其他指针(想想一个既是向量又是双向链表的结构)。因此,我不能使用默认的复制构造函数和赋值运算符,因为它们会指向原始元素而不是副本。注意:我确保向量永远不会在内存中调整大小或移动。

#include <type_traits>
#include <vector>

class DLXMatrix {
  private:
    struct Header {
        Header *left, *right;
    };
    std::vector<Header> heads;
  public:
    DLXMatrix() = delete;
    explicit DLXMatrix(size_t nb_col);
    DLXMatrix(const DLXMatrix &);
    DLXMatrix &operator=(DLXMatrix other);
    DLXMatrix(DLXMatrix &&) = default;
    DLXMatrix &operator=(DLXMatrix &&other) = default;
    ~DLXMatrix() = default;
};

static_assert(std::is_move_constructible<DLXMatrix>::value);
static_assert(std::is_move_assignable<DLXMatrix>::value);

如果我没记错的话,虽然我定义了自定义复制和赋值运算符,但默认析构函数、移动构造函数和移动赋值副本应该可以按预期工作而不会泄漏。现在,我想使用std::swap但它拒绝编译,因为我的类不可移动:

dlx_matrix.cpp:257:5: error: static_assert failed due to requirement
      'std::is_move_assignable_v<DLX_backtrack::DLXMatrix>'
    static_assert(std::is_move_assignable_v<DLXMatrix>);

所以我的问题是:

  • 这是一种合理的做事方式吗?
  • 为什么DLXMatrix不能移动分配?

如果重要的话,我将使用 g++ 7.5.0 和 clang++ 6.0.0 和标准 c++17 进行编译。

4

1 回答 1

0

我按照@IlCapitano 的指示发布了一个答案。

在实现过程中,operator=我需要做一个副本,并决定执行它,这要归功于按值调用。所以原型是

DLXMatrix &operator=(DLXMatrix other);

而不是标准

DLXMatrix &operator=(const DLXMatrix &other);

编译器/库不将这种按值调用的形式识别为正确的复制赋值运算符。

于 2020-11-12T16:56:46.113 回答