2013-04-02 3 views
1

Проще говоря, что случилось с этим фрагментом кода?C++: вставка кортежа в мультимножестве с функцией std :: и поддержанием порядка

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)); 
    } 

скомпилированы с использованием g++ 4.7.2 - с командой просто g++ -std=c++11 main.cpp

Почему я хочу это сделать?

Программа запускается в режиме реального времени и функция add_even_handler включает в себя значение типа double называется time (обратите внимание, что time переменных здесь не имеет ничего общего с часами или фактическое временем, это просто увеличением объект типа двойного) , Поэтому, когда пользователь добавляет какое-то событие, он будет вызываться в определенное время.

Универсальный контейнер под стандартом будет сортировать объекты в определенном порядке (обычно, если не всегда, std::less<T>). Затем, перейдя через контейнер, я мог бы вызвать Event при увеличении изменений переменной double time.

В чем проблема?

Как KyleC указывал (см свой ответ), std::function<> не понял компилятором в каком процессе заказа

Как я преодолел проблему

Вы узнаете что-то новое каждый день , Вышеприведенный код был результатом чрезмерного рассмотрения проблемы путем первоначального смешивания std::multiset и std::tuple. std::map<T,S> или std::multimap<T,S> также сортируется по соответствующему key, который в этом случае имеет тип double, который по умолчанию по стандарту снова std::less<T>. Таким образом, вместо того, чтобы выше, я сделал что-то похожее на следующем

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)); 
} 

Это только здесь написано в том случае, это может помочь людям, хотя и очевидны, но тем не менее.

+2

Можете ли вы опубликовать соответствующую часть ошибки? –

+0

@KyleC быстрый вопрос, как вы выводите ошибки компилятора в текстовый файл в g ++? – woosah

ответ

3

Проблема в том, что мультимножество упорядочено.

Ошибки вы получаете это:

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 

мультимножество не знает, как справиться с этим, потому что он не знает, как заказать мультимножество.

Внутренние контейнеры в мультимножестве сохраняют все свои элементы отсортированными , следуя критерию, указанному объектом сравнения. Элементы всегда вставлены в соответствующее положение после этого заказа .

Что не так с этим вектор:

- Основываясь на ваших комментариях, я думаю, что карта будет хорошо сочетать ваши цели.

std::map < float, Event > event_map; 
event_map.insert(std::make_pair(time, func_object)); 
+0

Хороший вопрос должен был это знать. Что вы предлагаете в следующем случае. Программа запускается в режиме реального времени, а функция 'add_even_handler' включает в себя значение типа' double', называемое 'time'. Поэтому, когда пользователь добавляет какое-то событие, он будет вызываться в определенное время. (обратите внимание, что время не имеет ничего общего с часами, это просто растущая переменная). В мультимножестве я предположил, что первый элемент 'tuple' будет автоматически отсортирован (что явно неправильно, как вы сказали). – woosah

+0

вам следует просто использовать std :: map , который должен работать для вас, поскольку float будет «ключом», который будет отсортирован. –

+0

@woosah см. Обновленный код выше для того, как использовать карту. –