在几个可变lambda中更改相同的向量

时间:2016-09-30 19:26:13

标签: c++ qt vector lambda

我有两个不同类型QPushButton*vector<QString>的Qt按钮。每个按钮都必须显示一个消息框,其中显示向量的最后一个元素的值是什么,如果用户按下是,则在向量中插入特定值。下面的代码显示了我是如何做到这一点的(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");
    }
});

我确定矢量在任何时候都是空的。

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

这似乎并不是说这是使两个lambdas捕获相同向量的正确方法。这是为什么?这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

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

您可以做的是创建std::shared_ptr<std::vector<QString>>并在每个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");
    }
});

另请注意,我将[myVector->size()]更改为[myVector->size() - 1],因为vector[size()]是您无法访问的向量的结尾。