refactor lambda由另一个类调用:同时保持调用者的代码仍然很短

时间:2016-10-13 09:49:51

标签: c++11 lambda

如何专业地重构lambda函数以便被另一个类调用WHILE使得调用者的代码仍然很短?

我的尝试表明,为了将lambda函数更改为普通函数,我必须手动捕获变量,因此新的普通函数需要更多参数(以补偿自动捕获能力)。

因此,新功能使用起来更加繁琐,并且可能导致更多错误。

实施例

这是我的原始代码,使用lambda。

void Turret::registerFullversion(int gameObjectId, PhysicObject* phyO){//utility
    //.... something a bit complex .......
}
void Turret::createTurret(int typeOfTurret){
    int gameObjectId=createNewGameObjectId();
    auto registerEasy=[&]( PhysicObject* phyO){
        //^ served as a short hand version of "registerFullversion"
        //  1 parameter is more comfortable than 2
        registerFullversion(gameObjectId,phyO);
    }
    switch(typeOfTurret){
        case 1:{ //this part will be moved into another class (###)
            PhysicObject* phy=PhysicSystem::createNewPhysicObject();
            registerEasy( phy);
            //^ equivalent to "registerFullversion(gameObjectId,phy)"
            //  but it is very concise (1 parameter), nice!
        };break;
        //..... a lot of case ....
    }
    //... do something about "gameObjectId"
}

我想将函数的一部分(###)从Turret移动到另一个类(TurretLaser)。

它有效,但结果是调用者必须捕获gameObjectId并手动传递它: -

void Turret::createTurret(int typeOfTurret){
    int gameObjectId=createNewGameObjectId();
    switch(typeOfTurret){
        case 1:{ //this part have to be move into another class
            TurretLaser::createTurret(gameObjectId)
        };break;
        //..... a lot of case ....
    }
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
    PhysicObject* phy=PhysicSystem::createNewPhysicObject();
    Turret:registerFullversion(gameObjectId,phy);
    //^ it is not as short as before  (now = 2 parameters)
}

注意

  • 在实际情况中,以上所有功能都是非静态功能,所有功能都要复杂得多。
  • 表现是第一要务。因此,std::bindstd::function是不允许的。
  • 这个问题询问如何省略捕获的参数而不是“请修复我的代码”,因此有效的解决方案也可以提供一个新的示例,其中包含自己的修复,而不是显示我的代码的修改。

我的尝试

我将手动捕获相关数据(gameObjectId)并对其进行缓存(使用新变量CACHE_gameObjectId): -

void Turret::registerEasy(PhysicObject* physicO){
    registerFullversion(CACHE_gameObjectId,physicO);
    //int "CACHE_gameObjectId" is a new field of "Turret"
};
void Turret::createTurret(int typeOfTurret){
    int gameObjectId=createNewGameObjectId();
    Turret::CACHE_gameObjectId=gameObjectId;
    switch(typeOfTurret){
        case 1:{ //this part have to be move into another class
            TurretLaser::createTurret(gameObjectId)
        };break;
        //..... a lot of case ....
    }
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
    PhysicObject* phy=PhysicSystem::createNewPhysicObject();
    Turret:registerEasy(phy);
    //^ short as before, nice
}

我的解决方案的缺点:脏,看起来很危险(不是那么自动,因此会导致更多的bug),似乎不那么线程安全(?)

0 个答案:

没有答案