2016-09-30 14 views
0

我有兩個不同的類型QPushButton*vector<QString>類型的Qt按鈕。每個按鈕都必須顯示一個消息框,其中顯示了矢量的最後一個元素的值,以及用戶是否按下了是向矢量中插入特定值。下面的代碼顯示了我如何做到這一點(QMessageBox::information僅出於調試原因)。這裏是我的代碼的相關部分:更改幾個可變lambda表示相同的向量

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認爲矢量是空的。

似乎並不是這是使兩個lambda捕獲與mutable相同的向量的正確方法。這是爲什麼?這樣做的正確方法是什麼?

+2

你已經從同一個變量移動了兩次。想想那是什麼。 – NathanOliver

+0

@NathanOliver好的,但是這樣做的正確方法是什麼?只使用lambda中的一個而不使用另一個lambdas就足夠了? –

+0

爲什麼不在每個lambda中存儲對向量的引用,如果它們應該共享呢? – NathanOliver

回答

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()]是一個過去然後結束矢量,你不能訪問的。

+0

我需要任何'#include'才能夠使用'std :: shared_ptr'嗎? –

+1

@DonaldDuck是的。 '#include '是你需要的。 Qt可能有自己的版本,如果你想堅持使用Qt類型。我只是使用'std',因爲它是標準的:-) – NathanOliver

+0

如果我想在lambda中使用另一個變量而不改變它,例如,如果另一個變量是'int myVar',我該怎麼做'[ myVar的,=]'? –

相關問題