Алиасы
Clone this wiki locally
Главная, Основные концепции, АОП, Адвайсы
Алиасы (или псевдонимы) позволяют обращаться к одному и тому же адвайсу используя разные теги (аналог символических ссылок в linux). Алиас внедряеться в аспект с помощью конструкции fas::alias:
typedef fas::alias<_foo_, _bar_> foo_advice;
Первым параметром задается новый тег, по которому можно обращаться к адвайсу помеченному тегом, который передается вторым параметром. Можно задавать алиас на алиас любого уровня вложенности, но в случае зацикливания, компилятор выдаст ошибку error: incomplete type ‘fas::recursive_alias...
.
Алиасы могут быть использованы для согласования адвайсов различных аспектов. Например, в примере ниже, используется адвайс для отображения значения счетчика, позаимствованный из некоторого "другого" проекта:
#include <fas/aop.hpp>
#include <iostream>
namespace other {
struct _value_;
struct ad_show
{
template<typename T>
void operator()(T& t) const
{
typedef typename T::aspect::template advice_cast<_value_>::type value_type;
value_type value = t.get_aspect().template get<_value_>();
std::cout << "value: " << value << std::endl;
}
};
} // namespace other
struct _counter_;
struct _inc_;
struct _dec_;
struct _show_;
struct ad_inc
{
template<typename T>
void operator()(T& t)
{
t.get_aspect().template get<_counter_>()++;
}
};
struct ad_dec
{
template<typename T>
void operator()(T& t)
{
t.get_aspect().template get<_counter_>()--;
}
};
struct counter_aspect: fas::aspect< fas::type_list_n<
fas::value_advice<_counter_, int>,
fas::advice<_inc_, ad_inc>,
fas::advice<_dec_, ad_dec>,
fas::advice<_show_, other::ad_show>,
fas::alias<other::_value_, _counter_>
>::type > {};
template<typename A = fas::aspect<> >
class counter
: public fas::aspect_class< typename fas::merge_aspect<A, counter_aspect>::type >
{
public:
void inc() { this->get_aspect().template get<_inc_>()(*this); }
void dec() { this->get_aspect().template get<_dec_>()(*this); }
int get() const { return this->get_aspect().template get<_counter_>(); }
void show() const { this->get_aspect().template get<_show_>()(*this); }
};
int main()
{
counter<> c;
c.inc(); c.inc(); c.inc();
c.dec();
c.show();
}
Алиас, как и любой другой адвайс, может быть замещен любым адвайсом. Этот прием может быть использован, когда изначально в разных участках кода используется один и тот же функционал, но есть вероятность, что в конкретном месте, пользователю потребуется заменить этот функционал так, чтобы в остальных местах использовался старый.