Orient Orient - 16 days ago 5
C++ Question

Make std::set to use conversion operator when compare elements

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?

Answer

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.