lambda匿名函式使用中的坑

峻峰飛陽發表於2016-04-28
void RoleManager::selectRole(const std::string &roleUid, const CallbackFunc &callback)
{
    ValueMap opData;
    opData["op"] = "selectrole";
    opData["roleuid"] = roleUid;
    Remote::getInstance()->execForeGroundOp(opData, [&](int result, ValueMap& respVm)
    {
                if (result == 0)
                {
                    m_role.m_uid = respVm["roleuid"].asString();
                    if (m_role.readLocalRoleData(roleUid))
                    {
                       ......
                    }
                    else
                    {

                       ......               

                    }

    }

其中CallbackFunc的定義為:

 typedef std::function<void(int, ValueMap&)> CallbackFunc;



這裡埋著一個大地雷,看到了嗎,我足足調了一下午,log打了幾十行,然後編譯再編譯。


roleUid是從外部傳來的 引用,注意是引用,當execForeGroundOp被呼叫時,roleUid已經被外部修改了,或者它僅僅是存在棧裡,走到execForeGroundOp函式時,那roleUid變數早就無效了。


正確的寫法,應該使用roleUid的複製,而不是引用,改法如下:

void RoleManager::selectRole(const std::string &roleUid, const CallbackFunc &callback)
{
    ValueMap opData;
    opData["op"] = "selectrole";
    opData["roleuid"] = roleUid;
    Remote::getInstance()->execForeGroundOp(opData, [this,roleUid](int result, ValueMap& respVm)
    {
                if (result == 0)
                {
                    m_role.m_uid = respVm["roleuid"].asString();
                    if (m_role.readLocalRoleData(roleUid))
                    {
                       ......
                    }
                    else
                    {

                       ......               

                    }

    }


相關文章