C++ 在多个可变lambda中更改相同的向量

C++ 在多个可变lambda中更改相同的向量,c++,qt,vector,lambda,C++,Qt,Vector,Lambda,我有两个不同的Qt按钮,类型分别为QPushButton*和向量。每个按钮都必须显示一个消息框,其中说明向量最后一个元素的值是什么,如果用户按“是”,则在向量中插入一个特定值。下面的代码显示了我是如何做到这一点的(仅出于调试原因,QMessageBox::information)。以下是我的代码的相关部分: std::vector<QString> myVector; myVector.push_back("First value"); QObject::connect(button

我有两个不同的Qt按钮,类型分别为
QPushButton*
向量
。每个按钮都必须显示一个消息框,其中说明向量最后一个元素的值是什么,如果用户按“是”,则在向量中插入一个特定值。下面的代码显示了我是如何做到这一点的(仅出于调试原因,
QMessageBox::information
)。以下是我的代码的相关部分:

std::vector<QString> myVector;
myVector.push_back("First value");
QObject::connect(button1,&QPushButton::clicked,myWidget,[myVector=move(myVector)]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector.size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + myVector[myVector.size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector.push_back("Value inserted by button 1");
    }
});
QObject::connect(button2,&QPushButton::clicked,myWidget,[myVector=move(myVector)]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector.size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + myVector[myVector.size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector.push_back("Value inserted by button 2");
    }
});
std::vector myVector;
myVector.push_back(“第一个值”);
QObject::connect(按钮1,&QPushButton::clicked,myWidget,[myVector=move(myVector)]()可变{
QMessageBox::information(NULL,“,std::to_string(myVector.size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+myVector[myVector.size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)==QMessageBox::Yes){
myVector.push_back(“按钮1插入的值”);
}
});
QObject::connect(按钮2,&QPushButton::clicked,myWidget,[myVector=move(myVector)]()可变{
QMessageBox::information(NULL,“,std::to_string(myVector.size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+myVector[myVector.size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)==QMessageBox::Yes){
myVector.push_back(“按钮2插入的值”);
}
});
我确信向量在任何时候都是空的

当我按下按钮1时,一切正常。但当我按下按钮2时,消息框显示向量的大小为0,我确信这不是真的。当我交换两个
QObject::connect
函数时,即将按钮2的函数置于按钮1的函数之前,按钮的行为交换:按钮2正常工作,按钮1认为向量为空


这似乎不是使两个lambda捕获可变向量的正确方法。为什么呢?正确的方法是什么?

在当前代码中,您将从向量移动两次。这样做会导致第二个lambda获得一个处于有效但未指定状态的向量。您需要做的是在两个lambda之间共享向量。由于您在一个要离开其作用域的函数中执行此操作,因此仅获取对向量的引用是不够的,因为向量将超出作用域,并且lambda将具有悬空引用

您可以做的是创建一个
std::shared_ptr
,并通过每个lambda中的值捕获该
shared_ptr
。这将确保向量具有适当的使用寿命,并且两个按钮在同一向量上操作。你的头发可能看起来像

std::shared_ptr<std::vector<QString>> myVector;
myVector->push_back("First value");
QObject::connect(button1,&QPushButton::clicked,myWidget,[=]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector->size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + (*myVector)[myVector.size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector->push_back("Value inserted by button 1");
    }
});
QObject::connect(button2,&QPushButton::clicked,myWidget,[=]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector.size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + (*myVector)[myVector->size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector->push_back("Value inserted by button 2");
    }
});
std::shared_ptr myVector;
myVector->push_back(“第一个值”);
QObject::connect(按钮1,&QPushButton::clicked,myWidget,[=])可变{
QMessageBox::information(NULL,“,std::to_string(myVector->size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+(*myVector)[myVector.size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)=QMessageBox::Yes){
myVector->push_back(“按钮1插入的值”);
}
});
QObject::connect(按钮2,&QPushButton::clicked,myWidget,[=]()可变{
QMessageBox::information(NULL,“,std::to_string(myVector.size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+(*myVector)[myVector->size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)=QMessageBox::Yes){
myVector->push_back(“按钮2插入的值”);
}
});

还要注意的是,我将
[myVector->size()]
更改为
[myVector->size()-1]
,因为
向量[size()]
超过了向量的末尾,您无法访问它。

在当前代码中,您从向量移动了两次。这样做会导致第二个lambda获得一个处于有效但未指定状态的向量。您需要做的是在两个lambda之间共享向量。由于您在一个要离开其作用域的函数中执行此操作,因此仅获取对向量的引用是不够的,因为向量将超出作用域,并且lambda将具有悬空引用

您可以做的是创建一个
std::shared_ptr
,并通过每个lambda中的值捕获该
shared_ptr
。这将确保向量具有适当的使用寿命,并且两个按钮在同一向量上操作。你的头发可能看起来像

std::shared_ptr<std::vector<QString>> myVector;
myVector->push_back("First value");
QObject::connect(button1,&QPushButton::clicked,myWidget,[=]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector->size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + (*myVector)[myVector.size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector->push_back("Value inserted by button 1");
    }
});
QObject::connect(button2,&QPushButton::clicked,myWidget,[=]() mutable{
    QMessageBox::information(NULL,"",std::to_string(myVector.size()).c_str());
    if(QMessageBox::question(NULL,"","The value of the last element in the vector is " + (*myVector)[myVector->size() - 1] + ".\nDo you want to insert a new value?",QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
        myVector->push_back("Value inserted by button 2");
    }
});
std::shared_ptr myVector;
myVector->push_back(“第一个值”);
QObject::connect(按钮1,&QPushButton::clicked,myWidget,[=])可变{
QMessageBox::information(NULL,“,std::to_string(myVector->size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+(*myVector)[myVector.size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)=QMessageBox::Yes){
myVector->push_back(“按钮1插入的值”);
}
});
QObject::connect(按钮2,&QPushButton::clicked,myWidget,[=]()可变{
QMessageBox::information(NULL,“,std::to_string(myVector.size()).c_str());
如果(QMessageBox::question(NULL,“,”向量中最后一个元素的值为“+(*myVector)[myVector->size()-1]+”\n是否要插入新值?”,QMessageBox::Yes | QMessageBox::No)=QMessageBox::Yes){
myVector->push_back(“按钮2插入的值”);
}
});

还要注意的是,我将
[myVector->size()]
更改为
[myVector->size()-1]
,因为
向量[size()]
超过了向量的末尾,您无法访问它。

您已经从同一变量移动了两次。想想这有什么用。@NathanOliver好吧,但是正确的做法是什么呢?只使用move i就够了吗