![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Extending ActorsBoost , Chapter 1. Phoenix 3.2.0 , Advanced Examples
|
выражение |
Семантика |
---|---|
< |
Возвращает итератор, указывающий на первый элемент в контейнере. |
< |
Возвращает итератор, указывающий на последний элемент в контейнере. |
< |
Возвращает размер контейнера, то есть его количество элементов. |
< |
Возвращает самый большой размер, который может иметь этот контейнер. |
< |
Эквивалент размера a.size() == 0. (Но, возможно, быстрее.) |
< |
Эквивалент свопа (a,b) |
Кроме того, мы хотим, чтобы все оператор () перегрузки обычного актера.
Первая версия нашего<container_actor
>интерфейса покажет общий принцип. Это будет постоянно расширяться. Для простоты каждый генератор функций элемента сначала возвращает<nothing
>.
template <typename Expr> struct container_actor : actor<Expr> { typedef actor<Expr> base_type; typedef container_actor<Expr> that_type; container_actor( base_type const& base ) : base_type( base ) {} expression::null<mpl::void_>::type const begin() const { return nothing; } expression::null<mpl::void_>::type const end() const { return nothing; } expression::null<mpl::void_>::type const size() const { return nothing; } expression::null<mpl::void_>::type const max_size() const { return nothing; } expression::null<mpl::void_>::type const empty() const { return nothing; } // Note that swap is the only function needing another container. template <typename Container> expression::null<mpl::void_>::type const swap( actor<Container> const& ) const { return nothing; } };
Хотя функции участника сейчас ничего не делают, мы хотим проверить, можем ли мы использовать нашего нового актера.
Во-первых, давайте создадим генератор, который обернет<container_actor
>вокруг любого другого выражения:
template <typename Expr> container_actor<Expr> const container( actor<Expr> const& expr ) { return expr; }
Теперь давайте проверим это:
std::vector<int> v; v.push_back(0); v.push_back(1); v.push_back(2); v.push_back(3); (container(arg1).size())(v);
Конечно, это не очень элегантно и не очень практично (мы могли бы просто использовать Феникс::begin(v) измодуля алгоритма Феникса, но мы можем сделать лучше).
Давайте возьмемзаполнитель аргумента, который можно использовать, как если бы это был контейнер STL:
container_actor<expression::argument<1>::type> const con1; // and so on ...
Приведенный выше пример можно переписать как:
std::vector<int> v; v.push_back(0); v.push_back(1); v.push_back(2); v.push_back(3); (con1.size())(v);
Вау, это было легко!
Это будет еще проще!
Во-первых, мы определяем ленивую функцию, которая оценивает выражение, которое мы хотим реализовать. Ниже приводится реализация функции размера:
struct size_impl { // result_of protocol: template <typename Sig> struct result; template <typename This, typename Container> struct result<This(Container)> { // Note, remove reference here, because Container can be anything typedef typename boost::remove_reference<Container>::type container_type; // The result will be size_type typedef typename container_type::size_type type; }; template <typename Container> typename result<size_impl(Container const&)>::type operator()(Container const& container) const { return container.size(); } };
Хорошо, это была первая часть. Во второй части будет реализована функция размера члена<container_actor
>:
template <typename Expr> struct container_actor : actor<Expr> { typedef actor<Expr> base_type; typedef container_actor<Expr> that_type; container_actor( base_type const& base ) : base_type( base ) {} typename expression::function<size_impl, that_type>::type const size() const { function<size_impl> const f = size_impl(); return f(*this); } // the rest ... };
В качестве упражнения пользователю остается выполнить недостающие части, повторно используя функции измодуля алгоритма Феникса(нетерпеливый взгляд здесь:container_actor.cpp).
Статья Extending Actors раздела Chapter 1. Phoenix 3.2.0 Advanced Examples может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Advanced Examples ::
реклама |