0
votes

Part of the class with multimap and his parameters

class cl_base
{
    string object_name;
    cl_base* p_parent = 0;

    struct o_sh {
        cl_base* p_cl_base;
        void (cl_base::*p_hendler) (cl_base* p_ob, string&);
    };

    multimap<void(cl_base::*) (string&), o_sh*> connects;
    multimap<void(cl_base::*) (string&), o_sh*>::iterator it_connects;

My method with problem

void cl_base::set_connect(void(cl_base::* p_signal) (string&), cl_base* p_ob_hendler, void(cl_base:: *p_hendler) (cl_base* p_pb, string&))
{
    void(cl_base::*p_key) (string&);
    o_sh* p_value;

    if (connects.size() > 0)
    {
        it_connects = connects.begin();
        while (it_connects != connects.end())
        {
            p_key = it_connects->first;
            p_value = it_connects->second;

            if ((p_key) == p_signal && (p_value->p_cl_base) == p_ob_hendler && (p_value->p_hendler) == p_hendler)
                return;
            it_connects++;
        }
    }
    p_value = new o_sh();
    p_value->p_cl_base = p_ob_hendler;
    p_value->p_hendler = p_hendler;
    connects.insert( {p_signal, p_value } );  //problem here
}

/usr/include/c++/7/bits/stl_function.h:386:20: error: invalid operands of types ‘void (cl_base::* const)(std::__cxx11::basic_string&)’ and ‘void (cl_base::* const)(std::__cxx11::basic_string&)’ to binary ‘operator<’ { return __x < __y; }

1
Pointers-to-member only support operators == and !=, not < , which multimap needs by default for its keys. You'll have to supply your own comparer as the map's third template parameter. - Etienne de Martel
"hendler" as in "handler"? - tadman
It's hard to see what the intended function of this code is, especially as you don't demonstrate using it. - tadman
Instead of words, can you demonstrate with code? It's always best to have a MCVE. - tadman
I'm trying to find out why this is so complicated. It could be pointless, or it could be necessary, and this is where some self-contained demonstration code helps a lot. - tadman

1 Answers

0
votes

Comparing two pointer-to-member-functions is harder than might at first appear. They are typically larger than normal pointers and cannot (for example) be cast to a long.

Here is a custom comparator that ought to work. I have to question the validity of doing this (and maybe there are some hidden gotchas), but I guess if you need it you need it.

class cl_base;

struct Compare
{
    bool operator () (void (cl_base::*lhs) (string &), void (cl_base::*rhs) (string &)) const
    {
        const int pm_size = sizeof (void (cl_base::*) (string &));
        struct
        {
            unsigned char buf [pm_size];
        } s_lhs, s_rhs;

        memcpy (&s_lhs, &lhs, sizeof (s_lhs));
        memcpy (&s_rhs, &rhs, sizeof (s_rhs));

        for (int i = 0; i < pm_size; ++i)
        {
            if (s_lhs.buf [i] < s_rhs.buf [i])
                return true;
        }

        return false;
    }
};

Then, as mentioned in the comments, change your multimap definition to:

multimap<void(cl_base::*) (string&), o_sh*, Compare> connects;