qt - 不能将多个结构添加到 qlist

qt - cannot add more than one struct onto a qlist

关于:

p.s.I 知道这是一个具体的问题,但我很茫然,不知道为什么会这样

下面的算法应该向列表中添加一个结构。每个结构都是一个 server_connection 对象,接收列表包含在另一个名为 VPN_Server.

的结构中

将结构添加到列表时,它只保存第一个添加的结构,不再添加。

调试器确认了这一点window:

对于每个新 IP,都会创建一个新的 VPN_Server 结构,并创建一个新的 server_connectionpush_back 进入 ServerInstancesList 列表。但是在foreach循环中,尝试添加对象是没有结果的。

问题:

server_connection 对象推送到特定 VPN_Server 结构时,它会将此数据保存在临时的 foreach 容器中,但不会应用它。

我试过了:

  1. 将自定义 addConnection() 方法添加到 VPN_Server struct

    void addConnection(server_connection s_con){ ServerInstancesList.push_back(s_con); }

  2. 正在创建一个临时列表,添加 server_connection 并创建一个新的 VPN_server 对象,并将其设置为等于当前的 foreach 容器。

None 这些帮助。

测试和深入描述:

在算法中,我的第 1 个和第 3 个 vpn_connection struct 具有相同的 IP。在第三次迭代时,执行 foreach 循环并发生以下情况。

VPN_Server ser 包含第一个结构信息的信息,即 IP 和其 QList<server_connection> 中的一个对象称为 ServerInstancesList

ser 通过 addConnection(s_con) 添加了一个对象。之后,循环以 return 终止。但是 ser 注册了添加的对象,而在 foreach 循环之外,没有添加新对象。甚至不包括列表中的任何结构。

这似乎很容易解决,但我就是找不到,

帮助将不胜感激!

代码:

server_connection

struct server_connection{

    //Is a connection contained by IP

    QString cipher,protocol;
    int port;
    bool lzo_compression;

    server_connection(){}

    server_connection(QString _cipher, QString _protocol, int _port, bool _comp){
        cipher = _cipher;
        protocol = _protocol;
        port = _port;
        lzo_compression = _comp;
    }
};

VPN_Server

struct VPN_Server{

    //Holds IP as sort value and list of connection info
    QString VPN_IP;
    QList<server_connection> ServerInstancesList;

    VPN_Server(){
        ServerInstancesList = QList<server_connection>();
    }

    VPN_Server(QString ip, QList<server_connection> server_con_list){
        VPN_IP = ip;
        ServerInstancesList = server_con_list;
    }

    void addConnection(server_connection s_con){
        ServerInstancesList.push_back(s_con);
    }
};

算法:

QList<VPN_Server> data_mananger::parseVPNConnections(QList<VPNConnection> l){

    //Init var
    QList<VPN_Server> server_list = QList<VPN_Server>();
    VPNConnection v_con;
    bool bAdded = false;
    server_connection s_con;

    //processing all vpn_connections, this is raw form sent, contains as fields, ip, cipher, protocol, port, compression
    foreach (v_con, l) {

        //create server_connection - data sorted by ip
        s_con = server_connection(v_con.cipher, v_con.protocol, v_con.port, v_con.lzo_compression);

        //pass through existing data, checking for a matching ip
        foreach (VPN_Server ser, server_list) {
            if (ser.VPN_IP == v_con.ip) {
                //ip match found -> there already exists and ip with a server connection, adding another one with s_con
                ser.addConnection(s_con);
                bAdded = true;
                //break current loop short searching for a matching ip
                break;
            }
        }

        //bAdded = false -> no matching IP has been found, thus creating a nw VPNServer
        if (!bAdded) {
            VPN_Server serv;
            //creating new connection list and adding s_con to this list
            QList<server_connection> list = QList<server_connection>();
            list.push_back(s_con);

            //adding VPNServer to list containing VPNServers
            serv = VPN_Server(v_con.ip, list);
            server_list.push_back(serv);
        }
        else
            //data has been added, reseting add flag
            bAdded = false;

    }
    return server_list;
}

感谢所有帮助过的人!

请访问 link 到下面的 QT 论坛,并为 VRonin 的解决方案点赞。

还有 kudo's@YuriyIvaskevych 在这里帮助我!

所以要重申 (budum tsss*) doc page

Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. [...] using a non-const reference for the variable does not allow you to modify the original container

解决方案:@VRonin from forum.qt.io

创建
for (auto serIter= server_list.begin(); serIter!=server_list.end(); ++serIter) {

    if (serIter->VPN_IP == v_con.ip) {
        //ip match found -> there already exists and ip with a server connection, adding another one with s_con
        serIter->addConnection(s_con);
        bAdded = true;
        //break current loop short searching for a matching ip
        break;
    }
}