Reputation: 27664
std::map's operator[] function returns an lvalue reference even though the map itself is an rvalue.
T& operator[]( const Key& key );
This causes undefined behavior usages like this one. Why are there no overloads for lvalue and rvalues like below? Does any other map implementation use such overloads?
T& operator[]( const Key& key ) &;
T operator[]( const Key& key ) &&;
Upvotes: 2
Views: 123
Reputation: 275385
#include <iostream>
#include <map>
bool silly_test( int& lhs, int& rhs ) { return lhs == rhs; }
std::map<int, int> silly_map() {
std::map<int, int> retval;
retval[0] = 0;
return retval;
}
int main() {
std::cout << silly_test( silly_map()[0], silly_map()[0] ) << "\n";
}
the above code is legal C++03, and illegal if we made the change you proposed.
While the above code is silly, it is an example of the fact that your change can break things.
rvalue references to this
where added late in C++11 standardization. Making potentially breaking changes to standard containers late in the cycle would probably be a bad idea.
I would encourage you to make a proposal to make the above change into the standard for C++1z. It may not be practical, but at first glance it looks like a decent idea, as the kind of code it breaks is pretty strange (and possibly should be broken).
Upvotes: 1