C ++ Lambda捕获空字符串

时间:2014-11-14 15:01:54

标签: c++ c++11 lambda

我有一个带有按钮的消息框类,点击后执行给定的功能:

// cMessage.h
#include "cButton.h"

class cMessage{
    public:
        std::vector<cButton*> button;
        cMessage(const std::vector<std::function<void()> >& effect);
        ~cMessage();
        void alert();};

// cMessage.cpp
cMessage::cMessage(const std::vector<std::function<void()> >& effect){
    for(unsigned int i = 0; i < effect.size(); i++)
        button.push_back(new cButton(effect[i], this)); }

cMessage::~cMessage(){
    for(unsigned int i = 0; i < button.size(); i++)
        delete button[i];}

void cMessage::alert(){
    delete this;}

// cButton.h
class cMessage;

class cButton{
    private:
        cMessage* alert;
        const std::function<void()> effect;
    public:
        cButton(const std::function<void()>& effect, cMessage* alert);
        void onClick();}

// cButton.cpp
cButton::cButton(const std::function<void()>& effect, cMessage* alert): effect(effect), alert(alert){}

void cButton::onClick(){
    if(alert)  alert->alert();
    if(effect) effect();}

当我传递一个lambda函数时会出现问题,因为当我让lambda函数捕获一个由字符串和unsigned int组成的对时,该字符串在执行函数时是空的。但是,unsigned int仍然是1。

// main.cpp
#include "cMessage.h"    

int main(){
    cMessage* message;
    {const pair<const string, const unsigned int> var("test", 1);
     std::function<void()> f = [var](){ std::cout << var.first << std::endl << var.second << std::endl; } };
     message = new cMessage( {f} );}
    message->button[0]->onClick();

    return 0;}

对于一些更多的couts,我发现在cButton的构造函数中,字符串仍然是&#34; test&#34;。 使它更奇怪的是,当我直接构造一个按钮时,问题不会发生。

解决了问题 它是由未定义的行为引起的,因为在删除按钮后调用了lambda函数(该按钮在它之前调用了它的消息导致它被删除)。这也解释了为什么直接创建按钮不会给出问题。让我感到惊讶的是,我还没有遇到任何其他问题。谢谢你的帮助

1 个答案:

答案 0 :(得分:0)

我建议重新思考

new cButton(this, effect[i]);

否则分享更多代码。

---编辑---

您粘贴的代码appears to produce the right output

#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <utility>

class cButton{
    private:
        const std::function<void()> effect;
    public:
        cButton(const std::function<void()>& effect);
        void onClick();};

cButton::cButton(const std::function<void()>& effect): effect(effect){}


class cMessage{
    public:
        std::vector<cButton*> button;
        cMessage(const std::vector<std::function<void()> >& effect);};


cMessage::cMessage(const std::vector<std::function<void()> >& effect){
    for(unsigned int i = 0; i < effect.size(); i++)
        button.push_back(new cButton(effect[i])); }


void cButton::onClick(){
    if(effect) effect();
    }

int main(){
    cMessage* message{};
    {
        const std::pair<const std::string, const unsigned int> var("test", 1);
        std::function<void()> f = [var](){ std::cout << var.first << std::endl << var.second << std::endl; };
        message = new cMessage( {f} );
    } 
    message->button[0]->onClick();
}

Output:
test
1