用 cd boost_1_34_1/boost; cpp -I /home/Administrator/boost_1_34_1 signal.hpp 产生预处理过的代码
combiner中要遍历并dereference每个元素,在dereference时用户connect上的函数才真正被调用,因此发生形如下面的sig(5,3)的调用时,实际上调用connect连接的函数的责任落在maximum身上(++和操作)
template<typename T>
struct maximum
{
typedef T result_type;
template<typename InputIterator>
T operator()(InputIterator first, InputIterator last) const
{
// If there are no slots to call, just return the
// default-constructed value
if (first == last)
return T();
T max_value = first++;
while (first != last) {
if (max_value < first)
max_value = first;
++first;
}
return max_value;
}
};
float product(float x, float y) { cout<<"product"<<endl; return xy; }
float quotient(float x, float y) { cout<<"quotient"<<endl; return x/y; }
float sum(float x, float y) { cout<<"sum"<<endl; return x+y; }
float difference(float x, float y) { cout<<"difference"<<endl; return x-y; }
int main(int argc, char argv[])
{
boost::signal<float (float x, float y), maximum<float> > sig;
sig.connect(&product);
sig.connect("ient);
sig.connect(&sum);
sig.connect(&difference);
std::cout << sig(5, 3) << std::endl;
}
output:
product
quotient
sum
difference
15
/////////////////////////////////////////////////////////////////
// change maximum to the following:
template<typename T>
struct maximum
{
typedef T result_type;
template<typename InputIterator>
T operator()(InputIterator first, InputIterator last) const
{
// If there are no slots to call, just return the
// default-constructed value
if (first == last)
return T();
T max_value = first++;
while (first != last) {
// if (max_value < first)
// max_value = first;
++first;
}
return max_value;
}
};
output:
product
15
Ref:
boost源码剖析之:多重回调机制signal(上)
http://www.ithao123.com/cpluspluslib/20071020/1677.html
——————————————————————————————————————————————————
template<
typename R,
typename T1, typename T2
,
typename Combiner,
typename Group,
typename GroupCompare,
typename SlotFunction
>
typename signal2<
R, T1, T2
,
Combiner, Group, GroupCompare, SlotFunction>::result_type
signal2<
R, T1, T2
,
Combiner, Group, GroupCompare, SlotFunction
>::operator()(T1 a1, T2 a2)
{
signals::detail::call_notification notification(this->impl);
signals::detail::args2<T1, T2> args(a1, a2);
call_bound_slot f(&args);
typedef typename call_bound_slot::result_type result_type;
optional<result_type> cache;
return combiner()(slot_calliterator(notification.impl->slots.begin(),
impl->slots_.end(), f, cache),
slot_calliterator(notification.impl->slots.end(),
impl->slots_.end(), f, cache));
}
call_notification::
call_notification(const shared_ptr<signal_base_impl>& b) :
impl(b)
{
// A call will be made, so increment the call depth as a notification
impl->call_depth++;
}
call_notification::~call_notification()
{
impl->call_depth–;
// If the call depth is zero and we have some slots that have been
// disconnected during the calls, remove those slots from the list
if (impl->call_depth == 0 &&
impl->flags.delayed_disconnect) {
impl->remove_disconnected_slots();
impl->flags.delayed_disconnect = false;
}
}
// 针对 signal2 分析
template<
typename R,
typename T1, typename T2
,
typename Combiner = last_value<R>,
typename Group = int,
typename GroupCompare = std::less<Group>,
typename SlotFunction = function2<
R ,
T1, T2>
>
class signal2 :
public signals::detail::signal_base,
public signals::trackable
{
public:
typedef SlotFunction slot_function_type;
typedef typename signals::detail::slot_result_type<R>::type
slot_result_type;
typedef T1 arg2_type; typedef T2 arg3_type;
typedef T1 first_argument_type;
typedef T2 second_argument_type;
private:
typedef signals::detail::group_bridge_compare<GroupCompare, Group>
real_group_compare_type;
typedef signals::detail::call_bound2<R>
outer_bound_slot_caller;
typedef typename outer_bound_slot_caller::template
caller<T1, T2
,
slot_function_type>
call_bound_slot;
public:
typedef typename Combiner::result_type result_type;
typedef Combiner combiner_type;
typedef slot<slot_function_type> slot_type;
typedef Group group_type;
typedef GroupCompare group_compare_type;
typedef signals::detail::slot_call_iterator<
call_bound_slot, iterator> slot_call_iterator;
explicit
signal2(const Combiner& c = Combiner(),
const GroupCompare& comp = GroupCompare()) :
signals::detail::signal_base(real_group_compare_type(comp),
c)
{
}
signals::connection
connect(const slot_type&,
signals::connect_position at
= signals::at_back);
signals::connection
connect(const group_type&, const slot_type&,
signals::connect_position at
= signals::at_back);
# 220 "/home/Administrator/boost_1_34_1/boost/signals/signaltemplate.hpp"
template<typename T>
void disconnect(const T& t)
{
typedef mpl::bool<(is_convertible<T, group_type>::value)> is_group;
this->do_disconnect(t, is_group());
}
private:
void do_disconnect(const grouptype& group, mpl::bool<true>)
{
impl->disconnect(group);
}
template<typename Function>
void dodisconnect(const Function& f, mpl::bool<false>)
{
signals::detail::callnotification notification(this->impl);
for (iterator i = impl->slots.begin(); i != impl->slots_.end(); ++i) {
slot_function_type& s = unsafe_any_cast<slot_function_type>(&i->second);
if (s == f) i->first.disconnect();
}
}
public:
result_type operator()(T1 a1, T2 a2);
result_type operator()(T1 a1, T2 a2) const;
Combiner& combiner()
{ return unsafe_anycast<Combiner>(&impl->combiner); }
const Combiner& combiner() const
{ return unsafe_anycast<const Combiner>(&impl->combiner); }
};
// iterator_facade<…> 是比较一般性的 iterator 基类,由它会调用子类的 dereference,increment 等
template<typename Function, typename Iterator>
class slot_call_iterator
: public iterator_facade<slot_call_iterator<Function, Iterator>,
typename Function::result_type,
single_pass_traversal_tag,
typename Function::result_type const&>
{
typedef iterator_facade<slot_call_iterator<Function, Iterator>,
typename Function::result_type,
single_pass_traversal_tag,
typename Function::result_type const&>
inherited;
typedef typename Function::result_type result_type;
friend class iterator_core_access;
public:
slot_call_iterator(Iterator iter_in, Iterator end_in, Function f,
optional<result_type> &c)
: iter(iter_in), end(end_in), f(f), cache(&c)
{
iter = std::find_if(iter, end, is_callable());
}
typename inherited::reference
dereference() const
{
if (!cache->is_initialized()) {
cache->reset(f(iter));
}
return cache->get();
}
void increment()
{
iter = std::find_if(++iter, end, is_callable());
cache->reset();
}
bool equal(const slot_call_iterator& other) const
{
iter = std::find_if(iter, end, is_callable());
other.iter = std::find_if(other.iter, other.end,
is_callable());
return iter == other.iter;
}
private:
mutable Iterator iter;
Iterator end;
Function f;
optional<result_type> cache;
};
// 看看调用 combiner operator() 的参数类型
typedef signals::detail::slot_call_iterator<
call_bound_slot, iterator> slot_call_iterator;
typedef typename outer_bound_slot_caller::template
caller<T1, T2
,
slot_function_type>
call_bound_slot;
typedef signals::detail::call_bound2<R>
outer_bound_slot_caller;
template<typename R>
struct call_bound2 {
template<typename T1, typename T2
,
typename F>
struct caller {
typedef args2<T1, T2>
args_type;
args_type args;
typedef R result_type;
caller() {}
caller(args_type a) : args(a) {}
template<typename Pair>
R operator()(const Pair& slot) const // 对应于前面的f(iter)调用
{
F target = const_cast<F>(unsafe_any_cast<F>(&slot.second));
return (*target)(args->a1, args->a2);
}
};
};