Сохранение сигнала boost::signal2 на карте?

Я столкнулся со следующей проблемой: я хочу сохранить ряд boost::signals2 сигнальные переменные на карте. Поскольку эти сигналы не подлежат копированию, это, очевидно, не будет работать. Как я могу обойти это? Я уже нашел этот старый вопрос. В нем плакат предлагает хранить сигналы как shared_ptr, Это единственный способ сделать это? Есть ли у него недостатки, или, что более важно, это безопасно?

3 ответа

Решение

Как было отмечено некоторыми комментаторами: Использование shared_ptrs для сигналов совершенно безопасно. Моя реализация работает и в то же время была тщательно протестирована, и я рад сообщить, что проблем действительно нет:)

Если сигналы не предназначены для совместного использования, вы можете сохранить boost::signal объекты, расположенные в куче внутри контейнера указателя ускорения:

Контейнер Boost.Pointer предоставляет контейнеры для хранения объектов, выделенных в куче, безопасным образом и с минимальными издержками.

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

Пример:

#include <iostream>
#include <map>
#include <string>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/signals.hpp>

void foo() {std::cout << "foo\n";}

void bar() {std::cout << "bar\n";}

int main()
{
    typedef boost::signal<void ()> Signal;
    boost::ptr_map< std::string, Signal> sigmap;
    sigmap["foo"].connect(&foo);
    sigmap["bar"].connect(&bar);
    sigmap["foo"](); // emit signal associated with "foo"
    sigmap["bar"](); // emit signal associated with "bar"
}

Поскольку он не копируемый и не может быть перемещен (возможно, он изменился в последней редакции). Для std::map, если вы не хотите использовать shared_ptr, вы можете использовать operator[] вместо методов insert или emplace, поскольку operator[] создает mapped_type, если key_value не существует. Очевидно, что это не решает проблему, когда вы хотите добавить сигнал с ранее назначенными слотами.

typedef boost::signal2... Signal;
std::map<int, Signal> sigmap;
sigmap[1]; // constructs signal using default constructor
sigmap[2].connect(slot); // constructs signal and connects slot
Другие вопросы по тегам