使用已删除的函数 'std::pair、std::basic_string >

发布于 2025-01-20 08:37:58 字数 1066 浏览 2 评论 0 原文

我正在使用 std::pairmake_pair() 使用这对字符串创建一个 std::map 。但我收到以下编译错误:

/opt/rh/devtoolset-7/root/usr/include/c++/7/ext/new_allocator.h:140:22: error: use of deleted function 'std::pair<const std::pair<std::basic_string<char>, std::basic_string<char> >, firmware_data>::~pair()'
  destroy(_Up* __p) { __p->~_Up(); }

我所做的声明如下:

typedef std::pair<std::string, string> FirmwareKey_t;
typedef std::map<FirmwareKey_t, firmware_data_t> FirmwareDataMap_t;

其中 firmware_data_t 是一个结构对象,定义为:

typedef struct firmware_data {
  string name;
  value_t abc; // value_t is of union type
  bool configurable;
  update_status_t def; //update_status_t is of enum type

} firmware_data_t;

Union 声明:

typedef union value {
  string string_val;
  bool boolean_val;
  int64_t int_val;
  uint uint_val;
} value_t;

I am using std::pair<string, string> and make_pair() to create a std::map using this pair of strings. But I am getting the following compilation error:

/opt/rh/devtoolset-7/root/usr/include/c++/7/ext/new_allocator.h:140:22: error: use of deleted function 'std::pair<const std::pair<std::basic_string<char>, std::basic_string<char> >, firmware_data>::~pair()'
  destroy(_Up* __p) { __p->~_Up(); }

The declarations I have done is as follows:

typedef std::pair<std::string, string> FirmwareKey_t;
typedef std::map<FirmwareKey_t, firmware_data_t> FirmwareDataMap_t;

Where firmware_data_t is a struct object, defined as:

typedef struct firmware_data {
  string name;
  value_t abc; // value_t is of union type
  bool configurable;
  update_status_t def; //update_status_t is of enum type

} firmware_data_t;

Union Declaration:

typedef union value {
  string string_val;
  bool boolean_val;
  int64_t int_val;
  uint uint_val;
} value_t;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心在旅行 2025-01-27 08:37:58

该错误表明 mapvalue_type (又名 std::pair)具有已删除的析构函数。

为此,可以使用 map::key_typemap::mapped_type 类型(在本例中为 FirmwareKey_tfirmware_data_t< /code> 分别)有一个已删除的析构函数。 FirmwareKey_t 显然不是这种情况,因此它必须是 firmware_data_t,其中包含 unionvalue_t 成员类型。 根据 cppreference

(C++11 起) 如果联合包含具有重要特殊成员函数(复制/移动构造函数、复制/移动赋值、或析构函数)的非静态数据成员, 该函数在联合中默认被删除,需要由程序员显式定义。

这意味着您的联合体中的一个字段是一种不平凡的类型,它定义了析构函数,因此联合体本身有一个已删除的析构函数,因此任何类型使用union作为数据成员的也有一个删除的析构函数,等等。

事实上,union 中的该字段是 string string_val 字段。

因此,您需要修复您的union。由于 std::string 需要销毁,因此您需要为 union 显式定义一个析构函数来调用 std::string 的析构函数,但是仅当 string_valunion 的活动字段时,例如:

union value_t {
  string string_val;
  bool boolean_val;
  int64_t int_val;
  uint uint_val;

  ~value_t() {
    if (some condition indicating string_val is active) {
      string_val.~string();
    }
  }
};.

您还需要为您的 union 定义复制构造函数和复制赋值运算符, 也。

话虽这么说,更好的解决方案是使用 std::variant 而不是联合std::variant 是一个类型安全的union,可以自动为您处理这些详细信息。

using value_t = variant<string, bool, int64_t, uint>;

The error is saying that the map's value_type (aka std::pair<const Key, T>) has a deleted destructor.

For that to happen, either the map::key_type or map::mapped_type type (in this case, FirmwareKey_t and firmware_data_t, respectively) has a deleted destructor. That is clearly not the case for FirmwareKey_t, so it must be firmware_data_t, which contains a value_t member of union type. According to cppreference:

(since C++11) If a union contains a non-static data member with a non-trivial special member function (copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.

Which means one of the fields in your union is of a non-trivial type that has a destructor defined, and so the union itself has a deleted destructor, and thus any type that uses the union as a data member also has a deleted destructor, and so on.

And, in fact, that field in your union is the string string_val field.

So, you need to fix your union. Since std::string requires destruction, you need to explicitly define a destructor for your union to call std::string's destructor, but only when string_val is the active field of the union, eg:

union value_t {
  string string_val;
  bool boolean_val;
  int64_t int_val;
  uint uint_val;

  ~value_t() {
    if (some condition indicating string_val is active) {
      string_val.~string();
    }
  }
};.

You will also need to define a copy costructor and copy assignment operator for your union, too.

That being said, a better solution is to use std::variant instead of a union. std::variant is a type-safe union that handles these details automatically for you.

using value_t = variant<string, bool, int64_t, uint>;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文