首页 > 解决方案 > 使用自定义类构造 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 得到了相同的结果。另外,你知道如何改进这个散列函数吗?

标签: c++hashsetunordered-set

解决方案


该错误并非特定于将Messages 放入集合中。

你在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_seqget_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;
}

推荐阅读