$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-22 23:18:27
Steven Watanabe wrote:
> AMDG
> 
> Markus Werle wrote:
>> Now we introduce another function call - not an operator 
>> this time, but in C++ these are equivalent.
>>
>> struct fun_t {};
>> terminal<fun_t>::type const fun = {{}};
>>
>> fun(a, b);
>>
>> This is represented by something similar to
>>
>> expr<
>>   tag::function
>>   ,args3<
>>      ref_<expr<tag::terminal, args0<fun_tag> > const>
>>     ,expr<tag::terminal, args0<> >
>>     ,expr<tag::terminal, args0<> >
>>     >
>>  >
>>
>> This is suprising. In contrast to operator+, the function fun
>> is treated as if it was an *operand*, not an *operator*.
>> The expression is not tagged by _the_ function call, but by a 
>> global this-is-a-function-tag and the function is stored in the
>> argument typelist.
>>   
> 
> I don't find it surprising.  This behavior is exactly what I would expect.
> 
> fun(a, b) is equivalent to fun.operator()(a, b).  In a concept fun(int, int)
> will be represented as
> 
> concept Callable<class T> {
>     void operator()(T, int, int);
> };
> 
> if I recall correctly.
Precisely. Another way to see this is to consider that the following 
might be a valid expression within a domain:
   (a+b)(a-b);
That's equivalent to (a+b).operator()(a-b). Clearly, this needs to be 
encoded as a binary tree with (a+b) as the left child and (a-b) as the 
right, with tag::function.
To see a real-world example that uses operator() this way, see:
http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/users_guide/examples/map_assign.html
It's an implementation of the map_list_of() function from the 
Boost.Assign library. It lets you initialize a map as follows:
     // Initialize a map:
     std::map<std::string, int> op =
         map_list_of
             ("<",1)
             ("<=",2)
             (">",3)
             (">=",4)
             ("=",5)
             ("<>",6)
         ;
>> What fun means is context dependent, I would expect the context
>> to take care about what fun_t might mean, so if we want 
>> symmetry first I'd expect a type representation similar to
>>
>> expr<
>>   tag::function<fun_t> 
>>   ,args2<
>>     ,expr<tag::terminal, args0<...ommitted...> >
>>     ,expr<tag::terminal, args0<...ommitted...> >
>>     >
>>  >
>>
>>
>> So I wonder whether this asymmetry was introduced due to the
>> fact that function objects could have a state which makes them
>> an in-between between operator and operand ...
>>   
> 
> IMO, a function object is not an operator at all.  The operator
> involved is the function call operator which takes a reference to
> the function object (*this) as the first parameter.  I don't see this
> as being any more asymmetric than any other member function call.
Right, it's perfectly symmetric with all the other operators.
-- Eric Niebler Boost Consulting www.boost-consulting.com