sách gpt4 ai đã đi

c++ - 预期 move_assignment 被删除

In lại 作者:行者123 更新时间:2023-12-05 05:39:35 26 4
mua khóa gpt4 Nike

我正在尝试编写一个有条件地禁用四个特殊成员函数(复制构造、移动构造、复制赋值和移动赋值)的包装类,下面是我用于测试目的的快速草稿:

enum class special_member : uint8_t {
copy_ctor, move_ctor,
copy_asgn, move_asgn
};

template
struct _disabled_wrapper {
công cộng:
constexpr _disabled_wrapper(MemberType type) : _type(type) {}

công cộng:
constexpr MemberType& unwrapped() { return _type; }
constexpr const MemberType& unwrapped() const { return _type; }

riêng tư:
MemberType _type;
};

template
struct _disabled_wrapper
{
riêng tư:
using _parent_t = _disabled_wrapper;

công cộng:
constexpr _disabled_wrapper(const _parent_t& parent) : _parent(parent) {}

constexpr _disabled_wrapper(const _disabled_wrapper&) = delete;
constexpr _disabled_wrapper(_disabled_wrapper&&) = default;
constexpr _disabled_wrapper& operator=(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper& operator=(_disabled_wrapper&&) = default;

công cộng:
constexpr MemberType& unwrapped() { return _parent.unwrapped(); }
constexpr const MemberType& unwrapped() const { return _parent.unwrapped(); }

riêng tư:
_parent_t _parent;
};

template
struct _disabled_wrapper
{
public: //Todo: Make private post fix.
using _parent_t = _disabled_wrapper;

công cộng:
constexpr _disabled_wrapper(const _parent_t& parent) : _parent(parent) {}

constexpr _disabled_wrapper(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper(_disabled_wrapper&&) = delete;
constexpr _disabled_wrapper& operator=(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper& operator=(_disabled_wrapper&&) = default;

công cộng:
constexpr MemberType& unwrapped() { return _parent.unwrapped(); }
constexpr const MemberType& unwrapped() const { return _parent.unwrapped(); }

riêng tư:
_parent_t _parent;
};

template
struct _disabled_wrapper
{
riêng tư:
using _parent_t = _disabled_wrapper;

công cộng:
constexpr _disabled_wrapper(const _parent_t& parent) : _parent(parent) {}

constexpr _disabled_wrapper(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper(_disabled_wrapper&&) = default;
constexpr _disabled_wrapper& operator=(const _disabled_wrapper&) = delete;
constexpr _disabled_wrapper& operator=(_disabled_wrapper&&) = default;

công cộng:
constexpr MemberType& unwrapped() { return _parent.unwrapped(); }
constexpr const MemberType& unwrapped() const { return _parent.unwrapped(); }

riêng tư:
_parent_t _parent;
};

template
struct _disabled_wrapper
{
riêng tư:
using _parent_t = _disabled_wrapper;

công cộng:
constexpr _disabled_wrapper(const _parent_t& parent) : _parent(parent) {}

constexpr _disabled_wrapper(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper(_disabled_wrapper&&) = default;
constexpr _disabled_wrapper& operator=(const _disabled_wrapper&) = default;
constexpr _disabled_wrapper& operator=(_disabled_wrapper&&) = delete;

công cộng:
constexpr MemberType& unwrapped() { return _parent.unwrapped(); }
constexpr const MemberType& unwrapped() const { return _parent.unwrapped(); }

riêng tư:
_parent_t _parent;
};

除了三种情况( , ),以上代码运行正常。具体来说,下面代码中的断言失败了,这让我相信由于某种原因默认的移动赋值运算符没有被删除,在 move_ctor ở giữa. _disabled_wrapper 的部分特化, 即使它的非静态成员 _parent已删除其移动分配。 cppreference.com 指出:

The implicitly-declared or defaulted move assignment operator for class T is defined asdeleted if any of the following is true:

  • T has a non-static data member that is const;
  • T has a non-static data member of a reference type;
  • T has a non-static data member that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator);
  • T has direct or virtual base class that cannot be move-assigned (has deleted, inaccessible, or ambiguous move assignment operator).

A deleted implicitly-declared move assignment operator is ignored by overload resolution.

这让我相信,根据标准,确实应该删除移动赋值运算符(要点三)。我缺少什么,或者,如果可能的话,我如何在不手动输入所有可能的特化的情况下使包装类按预期工作?谢谢。

int chính() {
using type = _disabled_wrapper;

//Passes, hence member variable has its move_assignment deleted as intended.
static_assert(std::is_move_assignable_v == false);
//Fails here! Move assignment defined?
static_assert(std::is_move_assignable_v == false);

trả về 0;
}

1 Câu trả lời

您引用中的最后一句话“重载决策忽略了已删除的隐式声明的移动赋值运算符。”更准确地说:

A defaulted move assignment operator that is defined as deleted is ignored by overload resolution.

class.copy.assign

kiểu 有一个默认的移动赋值运算符,它被定义为已删除,因为它在基类中被删除。

因此,重载决策会忽略此运算符。

因此,从右值赋值选择复制赋值。

Vì vậy,kiểu 是可移动赋值的,因为它是可复制赋值的。

关于c++ - 预期 move_assignment 被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72645574/

26 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com