简体   繁体   中英

use of deleted function 'std::pair<const std::pair<std::basic_string<char>, std::basic_string<char> >

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;

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>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM