I wrote an Edge
class like this:
struct Edge : public ::std::pair<int, int>
{
using ::std::pair<int, int>::pair;
int &src = first;
int &dst = second;
};
namespace std
{
template <>
struct hash<Edge>
{
std::size_t operator()(Edge const &x) const noexcept
{
return (x.src << 16) | x.dst;
}
};
}
So I can use src
/dst
to substitute first
/second
.
However, I found things go wrong when I use std::unordered_set
.
Edge e(1, 2);
print_edge_debug_info(e);
using _set_t = std::unordered_set<Edge>;
_set_t s;
s.insert(e);
for(auto &&_e : s) {
print_edge_debug_info(_e);
}
/*
output:
(1, 2) [ 2,0x7ffca1c08724] [ 2,0x7ffca1c08724]
(1, 2) [ 2,0x2bb80fc] [ 2,0x7ffca1c08724]
*/
print_edge_debug_info
:
inline void print_edge_debug_info(Edge const &edge)
{
std::cout << edge
<< " "
<< "[ " << edge.second << "," << &edge.second << "] "
<< " "
<< "[ " << edge.dst << "," << &edge.dst << "] "
<< std::endl;
}
The dst
and second
have the same address after the first Edge
object being constructed. But If I put this Edge
object into a std::unordered_set
and fetch it from the set, the addresses of the result's dst
and second
are different.
Besides, the new second
and the old second
have different address. But the new dst
and the old dst
have the same address. Which means the new dst
is the alias of the old second
, not the alias of the new second
.
It seems strange for me. I don't understand why this happened.
Is my way to make member aliases wrong? What's the correct way?
Aucun commentaire:
Enregistrer un commentaire