c++ - 使用自定义类构造 unordered_set
问题描述
我有一个 Message.hpp 类,它将在许多其他类中使用。我正在尝试制作一个 unordered_set,因为我将在其中添加和删除大量消息。
消息.hpp
class Message{
public:
//Constructors()
struct sockaddr_in get_dst(){
return dst;
}
std::string get_msg(){
return message;
}
bool is_ack(){
return ack;
}
int get_seq(){
return sequence_number;
}
bool operator==(const Message& m2) const{
return sequence_number == m2.get_seq() && dst.sin_port == m2.get_dst().sin_port && dst.sin_addr.s_addr == m2.get_dst().sin_addr.s_addr;
};
private:
bool ack;
int sequence_number;
std::string message;
struct sockaddr_in dst;
};
namespace std
{
template<>
struct hash<Message>{
size_t operator()(const Message& m) const
{
std::size_t h1 = std::hash<int>{}(m.get_seq());
std::size_t h2 = std::hash<unsigned short>{}(m.get_dst().sin_port);
std::size_t h3 = std::hash<in_addr_t>{}(m.get_dst().sin_addr.s_addr);
return h3 ^(h1 ^ (h2 << 1) << 1);
}
};
}
其他.hpp
class AckSet{
public :
//Constructor() and functions...
int find_msg(Message m){
/* checks if the message m is in ack_set*/
std::unique_lock<std::mutex> lock2(ack_set_mutex);
int seq = m.get_seq();
if (ack_set.find(m) != ack_set.end()){
return 0;
}
return -1;
}
void remove_msg(Message m){
/*
Finds a sequence number in the ack_set
*/
std::unique_lock<std::mutex> lock2(ack_set_mutex);
if (ack_set.erase(m) < 1){
exit(EXIT_FAILURE);
}
}
void check(UDPMessage *udplink){
std::unique_lock<std::mutex> lock(ack_set_mutex);
if (!stop.load()){
for (auto &a : ack_set){
udplink->sendMessage(a);
std::cout << "Resent message : " << a.get_seq() << " to " << a.get_dst().sin_port << " " << a.get_dst().sin_addr.s_addr <<"\n";
}
}
}
private :
std::atomic<bool> stop;
std::unordered_set<Message> ack_set;
std::mutex ack_set_mutex;
错误信息
将 'const Message' 作为 'this' 参数传递会丢弃限定符 [-fpermissive] return sequence_number == m2.get_seq() && dst.sin_port == m2.get_dst().sin_port && dst.sin_addr.s_addr == m2.get_dst( ).sin_addr.s_addr;
我的哈希函数和函数检查的 std::cout 得到了相同的结果。另外,你知道如何改进这个散列函数吗?
解决方案
该错误并非特定于将Message
s 放入集合中。
你在const
这里错了:
struct sockaddr_in get_dst(){
return dst;
}
std::string get_msg(){
return message;
}
bool is_ack(){
return ack;
}
int get_seq(){
return sequence_number;
}
bool operator==(const Message& m2) const{
return sequence_number == m2.get_seq() && dst.sin_port == m2.get_dst().sin_port && dst.sin_addr.s_addr == m2.get_dst().sin_addr.s_addr;
};
operator==
是const
,因此它不能调用非常量方法get_seq
或get_dst
.
当方法const
不改变对象时,默认创建方法:
struct sockaddr_in get_dst() const {
return dst;
}
std::string get_msg() const {
return message;
}
bool is_ack() const {
return ack;
}
int get_seq() const {
return sequence_number;
}