Я реализую свой собственный механизм signal
/slot (шаблон наблюдателя, стиль Qt), поэтому я могу иметь property
, который уведомляет... stuff... that is changed.
Я думаю, что С++ 11 обеспечивает все необходимое, чтобы сделать очень сукцинтами и возможную реализацию. "Проблема", с которой я сталкиваюсь, - это если я хочу "подключиться" к сигналу объекта const
, мне нужна функция signal::connect
, которая будет const, но изменит список обратных вызовов/наблюдателей. Есть два простых способа исправить это:
-
const_cast
списки внутриconnect
. - Сделайте списки
mutable
.
Оба кажутся мне похожими на то же (и это было задано до, например, в этом вопросе), и совершенно прекрасно логически, но стилистически сомнительно. Отсюда вопрос. Есть ли способ обойти это или это действительно оправданное использование const_cast
/mutable
?
Некоторый предварительный код, который у меня есть сейчас:
template<typename... ArgTypes>
class signal
{
public:
template<typename Callable>
void connect(Callable&& callback) const
{
std::lock_guard<std::mutex> lock(slots_mutex);
slots.emplace_back(callback);
}
void emit(ArgTypes... arguments) const
{
std::lock_guard<std::mutex> lock(slots_mutex);
for(auto&& callback : slots)
{
callback(arguments...);
}
}
private:
// mutable here allows to connect to a const object signals
mutable std::vector<std::function<void(ArgTypes...)>> slots;
std::mutex slots_mutex;
};
Примечание. Я не тестировал этот код; это всего лишь отражение моего нынешнего состояния ума.