Pergunta

Quite simply, what's wrong with this piece of code?

    typedef std::function<double()>                             Event;
    typedef std::tuple <double, std::function<double()>>        Event_handle;

    std::multiset < Event_handle > event_multiset;
    std::vector < Event_handle > event_vector;
    void add_event_handler(double time, Event func_object)
    {
        // multiset version gives an error 
        // event_multiset.insert (std::make_tuple(time, func_object));
        // vector is ok
        event_vector.push_back(std::make_tuple(time, func_object));
    }

compiled using g++ 4.7.2 - with command simply g++ -std=c++11 main.cpp

Why I want to do this?

The program is run in real time and the add_even_handler function includes a value of type double called time (note that time variable here has nothing to do with clock or actual time, it is just an increasing object of type double). Therefore when a user add some event it will be called at a certain time.

A multiset container under the standard would collate the objects in some order (usually, if not always, std::less<T>). Then looping over the container, I could call the Event upon increasing changes of variable double time.

What is the problem?

As KyleC has pointed out (see his answer), std::function<> is not understood by the compiler in what process to order

How I've overcome the problem

You learn something new everyday. The above code was a result of overthinking the problem by initially mixing std::multiset and std::tuple. std::map<T,S> or std::multimap<T,S> is also sorted by an associated key which in this case is of type double, which by default by the standard is again std::less<T>. So instead of the above, I've done something similar to the following

std::multimap <double, event> event_map;
void add_event_handler(double time, Event func_object)
{
    // multimap is ok
    event_map.insert(std::make_pair(time,func_object));
}

This is just written here in the event it may help people, albeit obvious but nonetheless.

Foi útil?

Solução

The problem is that multiset is ordered.

The error you are getting is:

Error   1   error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const std::function<_Fty>' (or there is no acceptable conversion)  
error C2088: '<' : illegal for class    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\tuple    52

The multiset doesn't know how to handle this because it does not know how to order the multiset.

Internally, multiset containers keep all their elements sorted following the criterion specified by its comparison object. The elements are always inserted in its respective position following this ordering.

What's wrong with using a vector?

-- Based on your comments, I think a map would suite your purposes nicely.

std::map < float, Event > event_map;
event_map.insert(std::make_pair(time, func_object));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top