Search code examples
c++variadic-templates

Applying function to a variadic template


I have a class that holds a map of Collection<T>, which is cast into a void* for storage purposes.

Each Collection<T> can hold an array of IDs, and I want to provide some variadic template magic to be able to tell if some ID exists in some grouping of Collection<T>. I'm just not sure how to go about it, after looking over some examples there is something that I am missing.

template<typename T>
class A {
public:
    void add_id(int id) {
        ids.emplace_back(id);
    }

    bool has(int id) {
        return std::find(ids.begin(), ids.end(), id) != ids.end();
    }

private:
    std::vector<int> ids {};

};

class Collection {
public:
    template<typename T>
    void insert(T* item) {
        items.insert({std::type_index(typeid(T)), reinterpret_cast<void*>(item)});
    }

    template<typename T>
    bool contains(int id) {
        return reinterpret_cast<T*>(items[std::type_index(typeid(T))])->has(id);
    }

    template<typename T>
    bool does_have(int id) {
        return contains<T>(id);
    }
    template<typename First, typename... Rest>
    bool does_have(int id) {
        return contains<First>(id) && does_have<Rest...>(id);
    }

    template<typename First, typename Second, typename... Rest>
    bool does_have(int id) {
        return contains<First>(id) && does_have<Second, Rest...>(id);
    }

private:
    std::map<std::type_index, void*> items;
};

Working Example

The idea is that, after storing some items in the Collection class, I can do something like

collection.does_have<A<int>, A<bool>, A<double>, A<float>>(15)

And if the ID 15 exists in all 4, then does_have returns true. Otherwise, it's false.


Solution

  • if you have c++17 (fold expression)

    template<typename ...Ts>
    bool does_have(int id) {
       return (contains<Ts>(id) && ...);
    }