Currently I use std::map
to save key/value pairs:
#include <map>
using K = int;
struct P {}; // some useful payload
int main()
{
std::map< K, P const > m;
m.insert({1, {}});
auto it = m.find(1);
// access:
it->first;
it->second;
}
int
here is just for example. mapped_type
is always const
in my use case.
To access payload P const
I have to use not too informative name second
. The same regarding first
. I want to name it simply payload
or somehow else.
To achieve this, I invent the following approach:
#include <set>
using K = int;
struct P {};
struct A
{
K key;
P payload;
operator K const & () const { return key; }
};
struct less
{
using is_transparent = void;
bool operator () (K const & l, K const & r) const
{
return l < r;
}
};
int main()
{
std::set< A, less > s;
s.insert({1, {}});
auto it = s.find(1);
// access:
it->key;
it->payload;
}
Here I make std::set
to use conversion operator every time for the key type. It works. But is it prohibited approach? Is there undefined behaviour?
To me, it looks technically valid.
But it also falls into the category of "making your code so unnecessarily complex that a programmer has to look twice or thrice at it before they comprehend what on earth you're doing, and can validate that you're doing it correctly, and for basically no tangible benefit" which is very ungood.
Indeed, the fact that you — the code's own author, no less! — felt the need to come here asking for a language lawyer to validate the code's correctness is a big red flag that this is likely not worthwhile.
If at any point you feel that .first
and .second
are insufficiently descriptive for your code, you can instead get around that locally with such magic as:
auto& key = it->first;
auto& payload = it->second;
or even:
auto& payload = getPayload(it);
where getPayload
is an appropriate function taking an iterator of your particular type.
These approaches have the benefit of being fairly obvious, and of not requiring convening a session of the C++ Supreme Court to check them over first.