2014-11-14 76 views
0

我有使得在被点击执行给定功能按钮一个消息类:C++ 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,但是,仍然是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我发现,在C按钮的构造函数,该字符串仍然是“测试”。 使它变得更加怪异的东西是,当我直接构造一个按钮时,问题不会发生。

问题(导致它被删除的按钮做了它的消息调用之前只是)解决 它是由不确定的行为造成的,因为lambda函数在按钮已被删除后调用。这也解释了为什么直接创建按钮不会产生问题。令我感到惊讶的是,我还没有任何其他问题。感谢您的帮助

+1

。你使用什么编译器? – Slava 2014-11-14 15:11:01

+0

MinGW,这实际上是产生错误的最小代码 – RTCgee 2014-11-14 15:12:43

+0

“效果”的类型是什么? – Barry 2014-11-14 15:13:22

回答

0

我建议重新思考

new cButton(this, effect[i]); 

否则分享更多的代码。

---编辑---

您粘贴appears to produce the right output代码:你应该创建http://stackoverflow.com/help/mcve

#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 
+0

我发现了这个问题,新的cButton(this,effect [i]);部分是必不可少的:通过这个参数,按钮会在按下按钮时提醒消息。该消息然后删除所有按钮和本身。但是在调用了这个alert函数之后,该按钮仍然使用了它的一些成员函数,导致了未定义的行为。 – RTCgee 2014-11-15 09:27:09