boost侵入式库,尤其是boost intrusive列表,是使用小型嵌入式系统(例如Cortex-M / R CPU)的出色实现。
但是,当在中断中将项目添加到列表中并在任务或其他中断的上下文中检查它们时,我希望该钩子应使用volatile
关键字进行限定。
volatile
并获取列表以接受模板参数?这是我需要帮助的地方,无法获取Observable::list_type
和Observer::list_hook_type
的模板来达成共识。这是我的最小示例代码,文件test_observer.cc
。 Boost库是1.66.0
并包含在-I /opt/boost
(这是符号链接/opt/boost@ -> boost_1_66_0
)中,编译方式为:
g++ -g -Wall -Wmissing-field-initializers -Wpointer-arith -Wuninitialized -Winit-self -Wstrict-overflow -Wundef -Wshadow -std=c++17 -I . -I /opt/boost/include test_observer.cc -o test_observer
使用Makefile的最小实现如下: https://github.com/natersoz/patterns/tree/master/observer/intrusive_list_member
/**
* @file test_observer.cc
* Test application for classes Observer and Observable.
*/
#include <boost/intrusive/list.hpp>
#include <iostream>
/** @class Observer. */
template <typename NotificationType>
class Observer
{
public:
virtual ~Observer() = default;
Observer() = default;
Observer(Observer const&) = delete;
Observer(Observer &&) = delete;
Observer& operator = (Observer const&) = delete;
Observer& operator=(Observer&&) = delete;
virtual void Notify(NotificationType const ¬ification) = 0;
using list_hook_type = boost::intrusive::list_member_hook<
boost::intrusive::link_mode<boost::intrusive::auto_unlink>
>;
list_hook_type hook;
};
template <typename NotificationType>
class Observable
{
public:
~Observable() = default;
Observable() = default;
Observable(Observable const&) = delete;
Observable(Observable&&) = delete;
Observable& operator = (Observable const&) = delete;
Observable& operator=(Observable&&) = delete;
/** Notify all observers of an event. */
void NotifyAll(NotificationType const ¬ification)
{
for (auto observer_iter = observer_list.begin();
observer_iter != observer_list.end();
)
{
Observer<NotificationType> &observer = *observer_iter;
++observer_iter;
observer.Notify(notification);
}
}
using list_type =
boost::intrusive::list<
Observer<NotificationType>,
boost::intrusive::constant_time_size<false>,
boost::intrusive::member_hook<
Observer<NotificationType>,
typename Observer<NotificationType>::list_hook_type,
&Observer<NotificationType>::hook>
>;
list_type observer_list;
};
static Observable<int> test_observable;
/**
* @class TestObserver
* A simple observer which gets notifications of integers.
*/
class TestObserver: public Observer<int>
{
public:
virtual void Notify(int const ¬ification)
{
std::cout << "notified: " << notification << std::endl;
};
};
static TestObserver test_observer_1;
int main(void)
{
test_observable.observer_list.push_back(test_observer_1);
test_observable.NotifyAll(1);
test_observable.NotifyAll(2);
test_observable.NotifyAll(3);
test_observable.NotifyAll(4);
return 0;
}