As title.
This compile error occurs when using the std::get<T>(pair)
, where the first member of the pair is a const, coming off an iterator for std::map
or std::unordered_map
.
To test the compile error, comment out the "notstd" overload of get
.
I have researched this question on Stack Overflow with the three most relevant questions listed below.
The existing answers lead me to believe that it should be a defect report, that the respective std::get
overload should have been added to the standard library, and that the automatic lifetime extension applied to temporary constant reference should be extended to cover such cases.
I have also researched whether it has to do with specialization of layouts (question 14272141, linked below). However, my code snippet only asks for the const reference to one of the two members; even with specialization of layouts, the const reference to either member should still exist.
I understand that casting between const std::pair<T, U>&
and const std::pair<const T, U>&
would not be safe, based on the existing answers.
namespace notstd
{
template <class T, class U>
const T& get(const std::pair<const T, U>& tu)
{
return tu.first;
}
}
int test(int value)
{
using namespace notstd;
using namespace std;
const std::pair<const int, bool> one(value, false);
const auto two = get<int>(one);
const auto three = get<const int>(one);
return 0;
}
Questions with high relevance:
(Humility notice: even though I claimed that this seems like a defect report, there may be some missing knowledge in my head, so please do let me know. From rioki's answer below, I can see that the current design allows distinguishing the two arguments in a std::pair<const int, int>
whereas my proposal would fail.)
My characterization of the present situation:
vector<pair>
and unordered_map<pair>
) are used together, and the explanation for this incompatibility is not exactly palatable to anyone including beginners and experienced programmers.const int
from an int
.), or that it cannot be improved without breaking existing code.Is this a defect in C++ that
std::get<T>(const std::pair<const T, U>& )
fail to compile due toconst T
?
No. I would very much expect this to fail:
std::pair<const int, bool> p(42, true);
std::get<int>(p); // expected failure
std::get<T>
means to retrieve the element whose type is T
. Not the element whose type approximates T
, or decays to T
, or any other such. std::get
comes to pair
by way of tuple
, where it is specified as:
Requires: The type
T
occurs exactly once inTypes...
. Otherwise, the program is ill-formed.
If we consider pair
as a special case of tuple
, int
does not occur exactly once in {const int, bool}
, so the program should be ill-formed.
Put in other words: you are asking for the int
in that pair, but there is no int
there. There's a const int
and there's a bool
.
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