6. Extending return type deduction system

ΥǤϡ桼α黻Ҥ򰷤ˡ ֤ͤηƥγĥˡ⤹롣 BLL ϥǥեȤα黻Ҥ֤ͤηƤ뤿ᡢ ¿ξˤϤɬפʤ 㤨С٤Ƥӱ黻ҤΥǥեȤ֤ͤ bool Ǥꡢ 桼ӱ黻Ҥ֤ͤη bool Ǥ¤ ֤ͤη饹οü첽ɬפϤʤ 줬ԲǤ⤢롣

Сɲǽʥ桼α黻Ҥϡñޤ黻ҤǤ롣 ΰοȤˡޤޤʱ黻Ҥ֤ͤη Ĥƥץ졼Ȥ롣 äơΥƥץ졼ȤȤü첽뤳Ȥˤꡢ֤ͤηƥĥ뤳ȤǤ롣 ñؿΤΥƥץ졼Ȥϡ plain_return_type_1<Action, A> return_type_1<Action, A> ǤꡢؿΤΤΤϡ plain_return_type_2<Action, A, B> return_type_2<Action, A, B> Ǥ롣

ƤΥƥץ졼ȤФ(Action) ϡ 黻ҤꤷƤ 饹Ǥ롣 Ʊ֤ͤηε§ä黻Ҥϡ 󥰥롼 ˤޤȤ졢 󥯥饹ȥ󥰥롼פΤߤ黻Ҥۣ椵褹롣 󤲤ȡoperator+򼨤 arithmetic_action<plus_action> 롣 ¾Υ󷿤δʥꥹȤ Table 2 ˼

ñؿξ A ؿξ A B ȤäĤΥƥץ졼Ȱϡ黻ҸƽФΰη򼨤Ƥ롣 ĤΥƥץ졼ȷ plain_return_type_n return_type_n (n ϣޤϣ) η󼨤λˤưۤʤ롣 ԤΥƥץ졼ȤǤϡηϾ˻ȷǤϤʤ ޤconst volatile ȤäҤĤƤʤ ˤꡢŪ˳ƥ桼α黻Ҥ黻ҷȤ˰Ĥü첽ԤǽʬȤʤ뤿ᡢü첽ñˤʤ롣 α黻ҤƱΰ˰ۤʤä const/volatile νҤĤꡢСɤ黻Ҥ֤ͤηۤʤˤϡ٤ɬפȤʤ롣 äơԤΥƥץ졼ȤǤϡη const/volatile νҤѹ󻲾ȷ⤽Τޤޤˤ롣 Ͼ嵭Τ褦ʥСɤ黻ҤΤˡǰξ罽ϻĤ return_type_2 ü첽ɬפȤʤ뤫⤷ʤȤǤ롣

桼η XYZ ФƱ黻Ҥ򥪡СɤȤ롣

Z operator+(const X&, const Y&);
Z operator-(const X&, const Y&);
ưʲǤϡ¦ΰη XǤꡢ¦ΰη Y ǤСΤ褦黻η̤η Z ǤȤü첽εҤɲäƤ롣
namespace boost { 
namespace lambda {
  
template<class Act> 
struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
  typedef Z type;
};

}
}
ü첽뤳Ȥˤꡢ BLL 嵭Ĥα黻Ҥ֤ͤη뤳ȤǤ롣 ü첽ϼפʥƥץ졼ȤȤȤˡ̾ ::boost::lambda ¸ߤʤФʤʤ ñΤˡʲǤϤ֤̾Ͼά롣

黻ҥ롼פü첽˲äơ ġα黻ҤȤü첽ԤȤǽǤ롣 㤨СηX Y Ǥ뻻ѱ黻ҤɲäȤ롣

X operator*(const X&, const Y&);
Ƥλѱ黻ҤФǽε§Ǥϡ ֤ͤη Z ȻꤷƤ롣 ϡξˤ餫ְäƤ롣 äơ;黻ҤФƼΤ褦˿§󶡤롣
template<> 
struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
  typedef X type;
};

ü첽ˤꡢη֤ͤηؤǤդΥޥåԥ󥰤뤳ȤǤ롣 Τ褦ˡǤηƥץ졼ȤȤŪʥ٥ȥ뤬äȤ롣

template <class T> class my_vector;
Ǥηδ֤˲ˡ黻ҤƤ¤ꡢ ʤĤ my_vector Υ󥿥󥹤δ֤ˤˡ黻ҤȤ롣 ˡη̤ my_vector Ǥηϡ Ĥ my_vector Ǥβˡη̤ηƱǤȤ롣 㤨Сmy_vector<int> my_vector<double> βˡη̤ my_vector<double> Ȥʤ롣 BLL ưʣǿδ֤ˡȤ߹ߤɸΰŪʷѴԤʤ饹äƤ롣 BLL εǽѤС嵭βˡ黻ҤϼΤ褦Ǥ롣
template<class A, class B> 
my_vector<typename return_type_2<arithmetic_action<plus_action>, A, B>::type>
operator+(const my_vector<A>& a, const my_vector<B>& b)
{
  typedef typename 
    return_type_2<arithmetic_action<plus_action>, A, B>::type res_type;
  return my_vector<res_type>();
}

my_vector βûηΤ˹ԤˡΤ褦Ǥ롣

template<class A, class B> 
class plain_return_type_2<arithmetic_action<plus_action>, 
                           my_vector<A>, my_vector<B> > {
  typedef typename 
    return_type_2<arithmetic_action<plus_action>, A, B>::type res_type;
public:
  typedef my_vector<res_type> type;
};
BLL Υƥץ졼 return_type_2 μºߤü첽ѤƤ롣 ΤˤϡηȷǤ뤳ȤɬפǤ롣

Table 2. Action types

+arithmetic_action<plus_action>
-arithmetic_action<minus_action>
*arithmetic_action<multiply_action>
/arithmetic_action<divide_action>
%arithmetic_action<remainder_action>
+unary_arithmetic_action<plus_action>
-unary_arithmetic_action<minus_action>
&bitwise_action<and_action>
|bitwise_action<or_action>
~bitwise_action<not_action>
^bitwise_action<xor_action>
<<bitwise_action<leftshift_action_no_stream>
>>bitwise_action<rightshift_action_no_stream>
&&logical_action<and_action>
||logical_action<or_action>
!logical_action<not_action>
<relational_action<less_action>
>relational_action<greater_action>
<=relational_action<lessorequal_action>
>=relational_action<greaterorequal_action>
==relational_action<equal_action>
!=relational_action<notequal_action>
+=arithmetic_assignment_action<plus_action>
-=arithmetic_assignment_action<minus_action>
*=arithmetic_assignment_action<multiply_action>
/=arithmetic_assignment_action<divide_action>
%=arithmetic_assignment_action<remainder_action>
&=bitwise_assignment_action<and_action>
=|bitwise_assignment_action<or_action>
^=bitwise_assignment_action<xor_action>
<<=bitwise_assignment_action<leftshift_action>
>>=bitwise_assignment_action<rightshift_action>
++pre_increment_decrement_action<increment_action>
--pre_increment_decrement_action<decrement_action>
++post_increment_decrement_action<increment_action>
--post_increment_decrement_action<decrement_action>
&other_action<address_of_action>
*other_action<contents_of_action>
,other_action<comma_action>