0

I have something like

class ClassB {
    // ....
private:
    static std::unordered_map<ClassA,double> activity;
    struct compare_values {
        bool operator()(const ClassA& l, const ClassA& r) const {
            return activity[l] < activity[r];
        }
    };
    std::set<ClassA,compare_values> ordered;
    // ...
}

Because I need ClassB to return the ClassA object with the maximum activity (only from the object in ordered), remove some ClassA object from the ordered set and insert new one inside.

How can I remove the static requirement for the unoredered_map? I want that every ClassB object have a compare_values that reference to the specific activity hash map, but I have no idea how to pass the map to them.

GiuMaz
  • 63
  • 1
  • 5
  • Is what you're saying that you don't know how to make a constructor that takes a container and moves/copies it into a non-static data member? Or do you want the map to be "external" and accessed through a member reference? – underscore_d Dec 22 '17 at 09:43
  • 1
    Such an entangled question... what is `maximum activity`? – Samer Tufail Dec 22 '17 at 09:50
  • Unless the comparison for two objects is guaranteed to be the same *always*, your code is broken. So `activity` should probably be `const`. If it can't be, then you have a problem. – juanchopanza Dec 22 '17 at 09:51
  • Sorry if the question is confusing, my english isn't really good. I want the map to be a private member of a ClassB object, and to be non static. I try to put a constructor in compare_values,that take a reference to the activity map, but I can't declare the ordered object with a calling to the constructor inside the template, right? – GiuMaz Dec 22 '17 at 09:56
  • ah, i see what you're asking. thinking... – Richard Hodges Dec 22 '17 at 09:59
  • @juanchopanza yes you are right, activity is constant and should be declared const. – GiuMaz Dec 22 '17 at 10:03

1 Answers1

2

Here's one way. Note that I have made the comparator copy/moveable with the use of an observer pointer rather than a reference:

#include <unordered_map>
#include <set>
#include <memory>

struct ClassA {};
std::size_t hash_value(ClassA const&);
bool operator==(ClassA const&, ClassA const&);

namespace std {
    template<>
    struct hash<::ClassA> {
        template<class Arg>
        auto operator()(Arg&& arg) const {
            return hash_value(arg);
        }
    };
}

class ClassB {

private:
    using activity_map = std::unordered_map<ClassA,double>;

    struct compare_values 
    {
        compare_values(activity_map const& activity)
        : activity_observer_(std::addressof(activity))
        {}

        bool operator()(const ClassA& l, const ClassA& r) const {
            return activity().at(l) < activity().at(r);
        }

    private:

        auto activity() const -> activity_map const&
        {
            return *activity_observer_;
        }

        activity_map const* activity_observer_;
    };
    activity_map activity {};
    std::set<ClassA,compare_values> ordered { compare_values { activity } };
    // ...
};

int main()
{
    ClassB b;
}

by request, refactored:

#include <unordered_map>
#include <set>
#include <memory>

struct ClassA {};
std::size_t hash_value(ClassA const&);
bool operator==(ClassA const&, ClassA const&);

namespace std {
    template<>
    struct hash<::ClassA> {
        template<class Arg>
        auto operator()(Arg&& arg) const {
            return hash_value(arg);
        }
    };
}

using ClassA_activity_map = std::unordered_map<ClassA, double>;

struct by_ascending_classA_activity 
{
    by_ascending_classA_activity(ClassA_activity_map const& activity)
    : activity_observer_(std::addressof(activity))
    {}

    bool operator()(const ClassA& l, const ClassA& r) const {
        return activity().at(l) < activity().at(r);
    }

private:

    auto activity() const -> ClassA_activity_map const&
    {
        return *activity_observer_;
    }

    ClassA_activity_map const* activity_observer_;
};


class ClassB {

private:

    ClassA_activity_map activity {};
    std::set<ClassA, by_ascending_classA_activity> ordered { { activity } };
    // ...
};

int main()
{
    ClassB b;
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142