简体   繁体   中英

How do I swap out all my private vectors for private maps in a C++ class?

I have a scene class for objects, cameras, and lights in my game

class Scene {
    private:
        std::vector<GameObject> objects;
        std::vector<Light> lights;
        // ... more containers ...

and I am trying to create a class interface that lets the user add, remove, retrieve, and iterate through these objects without giving them specific access to the underlying container (a vector at this point).

    public:
        GameObject& get_game_object(const unsigned int id);
        void add_game_object(const GameObject& object);
        void remove_game_object(const unsigned int id);

Adding, removing, and retrieving objects within the scene works fine.


I encounter a problem though, when attempting to iterate through these game objects.

    template<class T>
    void for_each_game_object(T t) const {
        std::for_each(begin(objects), end(objects), t);
    }

This "wrapper" works fine for my underlying class of vectors.

scene.for_each_game_object([] (GameObject& object) {
    // do something in the lambda
});

But now I want to swap out my vectors for unordered_maps where the key is an unsigned integer, and the value is the GameObject (or Camera or Light or etc.).

The for_each_game_object loop now requires a different lambda, and exposes the key/value pair to the end-user. Is there any way to rewrite the for_each_game_object loop to only iterate over the values of the map and ignore the ids (which are used internally by the Scene class)?

For the technical problem: pass a functor (eg a lambda) that invokes the client code's functor.

But do note that with a vector, if removing an object at a given index shifts the indices (id's) of the following objects, then the behavior with a map is different. So this change can break your existing client code. Ie the problem can be more than just the technical one of adapting a lambda.

This code maps a function over just the value part of a map's key/value pair:

class Wrapper
{
public:
    void Apply(const std::function <void (const std::string)>& functor)
    {
        for (auto i : _Map)
        {
            functor(i.second);
        }
    }
private:
    std::unordered_map<int, std::string>    _Map;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM