Home c++ Why std :: pair has a custom assignment operator, and does not...

Why std :: pair has a custom assignment operator, and does not use Default version?

Author

Date

Category

Why std :: pair has a custom assignment operator, and does not use Default version?

code from libC++ just makes the soil assignment, which would have done a default operator:

_ libcpp_inline_visibility
Pair & amp; Operator = (TypeName Conditional & LT;
          is_copy_assignable & lt; first_type & gt; :: value & amp; & amp;
          is_copy_assignable & lt; Second_Type & gt; :: Value,
        Pair, __nat & gt; :: Type Const & amp; __p)
  _Nothrow_copy_assignable & lt; first_type & gt; :: Value & amp; & amp;
        is_nothrow_copy_assignable & lt; Second_Type & GT; :: Value)
{
  first = __p.first;
  Second = __p.second;
  RETURN * THIS;
}

Copy constructor, for example, uses default implementation, so this is not Code Style:

pair (pair const & amp;) = default;

Answer 1, Authority 100%

In the language standard, this operator is declared explicitly. If you look at a note to this operator, then it says

Remarks: This operator is defined as deleted unless is_copy_assignable_v & lt; first_type & gt; is True and is_copy_assignable_v & lt; second_type & gt; is True .

That is, the arguments of the template must satisfy the requirements of std :: is_copy_assignable .
std :: is_copy_assignable requires the first argument to be assigned from the constant second: std :: is_assignable & lt; t & amp;, const t & amp; & gt; .

In turn, STD :: IS_ASSIGNABLE Must give True if the expression STD :: DECLVAL & LT; T & GT; () = STD :: DECLVAL & LT; U & GT ; () is compiled, i.e. Object type T You can assign an object like U .

i.e. The following code should not be compiled:

std :: pair & lt; int [4], int & gt; P1;
STD :: PAIR & LT; INT [4], int & gt; P2;
p2 = p1; // should be a mistake

So, if you leave the default statement, it will not be errors. Let’s make imitation on your own class:

template & lt; TypeName T & GT;
Struct Tester.
{
  Tester & amp; operator = (Tester Const & amp;) = Default;
  T mem;
};
TESTER & LT; INT [4] & gt; P1;
TESTER & LT; INT [4] & gt; P2;
p2 = p1; // no error
Using Type = int [4];
static_assert (std :: is_copy_assignable_v & lt; type & gt;, ""); // Error

As we see, the error is missing, although static_assert shows that the int [4] type does not satisfy the requirements of is_copy_assignable .

Therefore, an implicitly generated assignment operator is not suitable.

However, already explicitly written operator passes our test and we get an error when assigning arrays.

tester & amp; Operator = (Tester Const & Amp; RHV)
{
  mem = rhv.mem;
  RETURN * THIS;
}

Additionally, you need to “hang out” the compilation time checks, as is done in the example given in the question.


Answer 2, Authority 40%

In order for the assignment operator to work even with types, instantiated links.

https://godbolt.org/z/jq648q

# include & lt; iostream & gt;
TEMPLATE & LT; Class T1, Class T2 & GT;
STRUCT PAIR {
  T1 FIRST;
  T2 Second;
  // Pair & amp; Operator = (Const Pair & amp;) = default; // 1
  Pair & amp; Operator = (Const Pair & amp; RHS) {// 2
    first = rhs.first;
    Second = Rhs.second;
    RETURN * THIS;
  }
};
INT MAIN () {
  int x = 1, y = 2;
  pair & lt; int & amp;, int & gt; p1 {x, y}, p2 {y, x};
  p1 = p2;
  STD :: COUT & LT; & LT; p1.first & lt; & lt; p1.second & lt; & lt; p2.first & lt; & lt; p2.second & lt; & lt; '\ n';
} 

If you comment out 2 here and uncomment 1, it won’t work, but now it does.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions