Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - Copy Assignment Operator is Implicitly Deleted

Tags:

c++

templates

I'm trying to use copy assignment in the following case.

There're two template classes, list map and xpair.

template <typename Key, typename Value, class Less=xless<Key>>
class listmap {
public:
   using key_type = Key;
   using mapped_type = Value;
   using value_type = xpair<const key_type, mapped_type>;     //value_type
...
}

template <typename First, typename Second>
struct xpair {
   First first{};
   Second second{};
   xpair(){}
   xpair (const First& first, const Second& second):
           first(first), second(second) {}
};

In the main.cpp, I tried to write,

using commend = string;
using str_str_map = listmap<string,string>;
using str_str_pair = str_str_map::value_type;    //value_type, to be replaced
using commend_pair = xpair<commend, str_str_pair>;

int main(...) {
   commend_pair cmd_pair;
   str_str_pair newPair ("Key", "value");
   cmd_pair.second = newPair;

   ...
}

It gives me an error saying

  object of type 'xpair<const std::__1::basic_string<char>,
  std::__1::basic_string<char> >' cannot be assigned because its copy
  assignment operator is implicitly deleted

If I replace

using str_str_pair = str_str_map::value_type;

to

using str_str_pair = xpair<string, string>;

Everything works fine. Why is that? Shouldn't value_type = xpair<string, string>?

like image 843
Kevin217 Avatar asked Feb 09 '16 18:02

Kevin217


People also ask

When is an implicitly-declared Copy assignment operator defined as deleted?

An implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true: T has a user-declared move assignment operator.

How is the copy assignment operator defined in C++?

If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used or needed for constant evaluation (since C++14). For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove ).

What is a defaulted copy assignment for Class T?

T has a user-declared move assignment operator. Otherwise, it is defined as defaulted. A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

What is copyassignable in C++?

A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or const volatile T&. For a type to be CopyAssignable, it must have a public copy assignment operator.


2 Answers

I don't see where newPair is declared, but the error message seems like enough.

Why this fails: If either element in the pair is const, the assignment operator for that element is itself deleted. You couldn't assign to a const string but that's exactly what you're asking it to do when you assign to pair<const string, T>. To simplify the example

std::pair<const int, int> p(0, 0);
p.first = 1; // no, can't assign to p.first
p = std::pair<const int, int>(1, 2); // no, requires assigning to p.first

Why maps have const key types: map containers organize their elements based of the keys. If you changed a key, the map wouldn't be able to find it anymore. Consider:

std::map<string, int> m = { ... };
auto it = m.find(k);
it->first = "a different value";

Since a std::map for example, is internally organized as a red-black tree, changing the key safely would require a reorganization of the node. However in this example you're operating directly on the pair in the node. Changing the key would require removing the pair from m, then putting it back in with a changed key.

like image 95
Ryan Haining Avatar answered Oct 18 '22 20:10

Ryan Haining


You have

using value_type = xpair<const key_type, mapped_type>;

Since you are using a const key_type you are no longer able to assign to it since key_type is const.

using str_str_pair = xpair<string, string>;

Works as neither string is const

like image 39
NathanOliver Avatar answered Oct 18 '22 22:10

NathanOliver