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.