0

C++0x のラムダを使用してブースト関数を定義しています。ラムダ/ブースト関数を使用して動作の一部を定義するクラスがいくつかあります。私が疑問に思っていたのは、関数定義を変更せずに、クラスに関するデータをラムダのコンテキストに公開することは可能ですか? たとえば、次のようなクラスのセットがあります。

class ConsumableItem : public Item
{
public:
    //Constructors here
    virtual bool Use(std::set<Character::BaseCharacter*> Users, std::set<Character::BaseCharacter*> Targets);
    virtual bool Use(std::set<Battles::BattleCharacter> Users, std::set<Battles::BattleCharacter> Targets, Battles::BattleField &field);
protected:
    bool UseRegularFunction;
    boost::function<void(std::set<Character::BaseCharacter*>, std::set<Character::BaseCharacter*>)> RegularUse;
    bool UseBattleFunction;
    boost::function<void(std::set<Battles::BattleCharacter>, std::set<Battles::BattleCharacter>, Battles::BattleField &)> BattleUse;
};

class StatBoostingItem : public ConsumableItem
{
public:
    StatBoostingItem(int UID, std::string &name, std::string &descript, boost::unordered_set<ItemFlags> Flags, boost::unordered_map<Stat, int> &boosts, int value);
protected:
    virtual bool Use(std::set<Character::BaseCharacter*> Users, std::set<Character::BaseCharacter*> Targets) override;
    virtual bool Use(std::set<Battles::BattleCharacter> Users, std::set<Battles::BattleCharacter> Targets, Battles::BattleField &field) override;
private:
    boost::unordered_map<Stat, int> StatBoosts;
}

そして、統計ブーストアイテムのコンストラクター内で、これを実行できるようにしたいと思います:

StatBoostingItem::StatBoostingItem(int UID, std::string &name, std::string &descript, boost::unordered_set<ItemFlags> Flags, boost::unordered_map<Stat, int> &boosts, int value)
    : ConsumableItem(UID, name, descript, Flags, ItemClass::STAT_BOOSTING_ITEM, value)
{
    StatBoosts = boosts;
    RegularUse = [](std::set<Character::BaseCharacter*> users, std::set<Character::BaseCharacter*> targets)
    {
        for (auto character = targets.begin(); character != targets.end(); ++character)
        {
            for (auto statBoost = StatBoosts.begin(); statBoost != StatBoosts.end(); ++statBoost)
            {
                //Item Effect in here
            }
        }
    };
}

これは単なる好奇心です。boost::function 定義を単純に拡張して、問題の項目へのポインターを含め、その方法でデータを取得したり、Use 関数をオーバーライドしたりできることを知っているからです。しかし、それを含むクラスに関する情報を何らかの方法でラムダに公開できれば、それを他の場所でも利用できるので理想的です

4

1 に答える 1

3

ラムダから StatBoostingItem::StatBoostingItem のスコープで使用可能な変数にアクセスする必要がありますか? その場合、単純にcaptures を使用できます:

RegularUse = [&](std::set<Character::BaseCharacter*> users, std::set<Character::BaseCharacter*> targets)

[&] は、参照によって現在のスコープからすべてをキャプチャするようにラムダに指示します。特定の変数だけが必要な場合は、その変数だけをキャプチャできます。また、[=] を使用してすべてを値でキャプチャすることもできます。[this] を使用して、Item インスタンスへのポインターをキャプチャすることもできると思います。

RegularUse = [this](std::set<Character::BaseCharacter*> users, std::set<Character::BaseCharacter*> targets)

それを試したことはありませんが、うまくいかない理由はわかりません。それが機能しない場合 (ラムダはメソッドではありませんが、何らかの形で予約されているため)、別の変数にthis割り当てて代わりにキャプチャすることで、いつでも回避できます。this

Item* item = this;
RegularUse = [item](std::set<Character::BaseCharacter*> users, std::set<Character::BaseCharacter*> targets)
{
    item.DoSomething();
}
于 2011-05-13T04:30:15.910 に答える