vendredi 14 octobre 2022

Keying an (unordered_)map using a multimap iterator

I'm building a software where one class is responsible to log info sources and commands (both are grouped as requests), where all requests are inserted inside a multimap, wherein the multimap is keyed by the request name, and each element points to request structure that holds management information and callback function pointer, insighted from this software.

The callbacks are executed to issue a command, or to get an info, and everything is ok until here.

To enable subscription-based information delivery, I've introduced a new map keyed by the request iterator, so where calling subscribe("infoID") the software looks for the exact match request and return its iterator.

Because these iterators are unique per request, I've found it useful to key the subscriptions map using it. Where the key points to info subscriber's callback-functions.

The error is:

error: no match for 'operator<' (operand types are 'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>' and 'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>') { return __x < __y; }

Followed by 15 compiling notes 'template argument deduction/substitution failed':

'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>' is not derived from 'const std::pair<_T1, _T2>' { return __x < __y; } each one with a unique source: const std::pair<_T1, _T2>, const std::reverse_iterator<_Iterator> (stl_function.h), const std::reverse_iterator<_Iterator> (stl_iterator.h), ... etc.

Full error here.

Code:

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <functional>
#include <map>

using namespace std;

struct request
{
    string f1;
};

using   SYS_REQMAP          =unordered_multimap<string, request, hash<string>>;
using   SYS_REQMAP_I        =SYS_REQMAP::iterator;

using SYS_INFOSUB_CBF   = function<void(string, string)>;
using SYS_INFOSUB_CBFS  = vector<SYS_INFOSUB_CBF>;

using SYS_REQINF_SUBS   = map<SYS_REQMAP_I, SYS_INFOSUB_CBFS>;

void cbf(const string& a, const string& b){}
int main()
{
    SYS_REQINF_SUBS infoSubr;
    SYS_REQMAP vm,
                {"cmd2", {"bar"}}};

    for (SYS_REQMAP_I it = vm.begin(); it != vm.end(); it++)
    {
        printf("%lu\n", it);
        infoSubr[it].push_back(cbf);    // Compile error
    }
}

void compilesOK()
{
    using SYS_REQINF_SUBS_1 = std::map<int, SYS_INFOSUB_CBFS>;
    SYS_REQINF_SUBS_1 subs1;
    subs1[1].push_back(cbf);    // Compiles OK
}

And here's OnlineGDB link to compile and observe output.

Aucun commentaire:

Enregistrer un commentaire