With C++23 there will be
std::pair<T1, T1>::operator =( const pair &other ) const;
For me an assignment-operator operating on const-objects doesn't make any sense since the object can't be modified. Why will C++23 have this operator on pair ? And even more confusing, there's:
std::pair<T1, T1>::operator =( pair &&other ) const;
[EDIT]: This won't work because what this points to will be const:
template<typename T>
struct S
{
void operator +=( T x ) const;
T m_x;
};
template<typename T>
void S<T>::operator +=( T x ) const
{
m_x += x;
}
int main( int argc, char **argv )
{
S<int> si;
si += 1;
}
So why is there a const-qualified assignment-operator with pair ?
It makes sense for pairs of non-const references. Those remain assignable even when const. Consider:
#include <iostream>
template <typename T>
void foo(const T x) {x = 42;}
int main()
{
int y = 1;
foo<int &>(y);
std::cout << y << '\n'; // 42
}
But why bother supporting it in std::pair?
I've recently seen an explanation somewhere on SO, but can't find the link (found it). It went along the lines of:
You're making a generic algorithm, and you're assigning to a function result in a template (such as to a dereferenced iterator). If the function happens to return by value, you can silently get unexpected behavior (assignment doing nothing).
You would like a compilation error instead, but virtually nobody
&-qualifies their assignment operators.
Then a logical next step is to check the return type and reject non-references.
But you want to leave a loophole. E.g. dereferencing std::vector<bool> iterator returns (a proxy object) by value, and assigning to it should be allowed.
You could invent a type trait for it, but there's a clever alternative. You check if the assignment still compiles if you add const to the return type. If it doesn't, you raise a compilation error. This generalizes nicely to returning references, since adding const to them leaves the type unchanged (and still assignable, if the reference was non-const).
To make it work, you need to add const to assignment operators of all such types (and it was done for std::vector<bool>::reference).
As for why std::pair (and std::tuple) need it: iterators from std::views::zip() dereference to tuples of references, and you want to be able to assign to those tuples.
But I don't remember which standard algorithms are going to be constrained like this in C++23. Probably something in ranges...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With