因此,我正在用c++实现一个TCP服务器,并将所有用户存储在一个 vector 中。现在,我需要一个更通用的函数来搜索多个不同的属性,如何改进此代码?

struct client {
    std::string ip_address = "";
    int socket_id = 0;
    bool blocking = false;
};

enum client_codes {
    ip_address,
    socket_id,
    blocking,
};

template<typename T>
std::vector<client>::iterator search_vector(std::vector<client> &list, int type, T query) {

    std::vector<std::function<bool(client)>> comparators;

    comparators.push_back([&](client ob) {return ob.ip_address == std::to_string(query); });
    comparators.push_back([&](client ob) {return ob.socket_id == query; });
    comparators.push_back([&](client ob) {return ob.blocking == query; });

    return std::find_if(std::begin(list), std::end(list), [&](client obj) {return comparators[type](obj); });

}

// Implementation
std::vector<client> client_list;
auto search1(search_vector(client_list, socket_id, 321));
auto search2(search_vector(client_list, blocking, true));
auto search3(search_vector(client_list, ip_address, "192.168.0.85"));

最佳答案

由于您正在搜索相同类型的不同属性,因此我想这是pointers to members的罕见用例。以下代码应有助于清除此问题:

struct client {
    std::string ip_address = "";
    int socket_id = 0;
    bool blocking = false;
};

// search_vector accepts a pointer to member of type T, and a value of type T
template<typename T>
std::vector<client>::iterator search_vector(std::vector<client>& list, T client::*member, T value){
    return std::find_if(list.begin(), list.end(), [value, member](const client& c){ return c.*member == value; });
}

这就是您现在使用它的方式,而无需任何额外的enums或特殊逻辑。
auto it1 = search_vector(client_list, &client::socket_id, 321);
auto it2 = search_vector(client_list, &client::blocking, true);
auto it3 = search_vector(client_list, &client::ip_address, "192.168.0.85");

当然,这个确切的search_vector函数仅限于成员变量和完全相等测试。但是用诸如get_ip_address()之类的成员函数的指针扩展该函数将非常简单。

为了更笼统,用std::function<bool(T)> condition代替T value这样的重载还可以在您不希望完全相等时帮助您进行更具体的搜索。

关于c++ - 如何改善 vector 搜寻功能?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55315806/

10-15 17:29