
On 03/22/08 22:18, Eric Niebler wrote:
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.
In mpl, this is called apply instead of function. Here: boost-trunk/libs/mpl/doc/refmanual/apply.html it appears as: template< typename F, typename A1,... typename An > struct applyn { typedef unspecified type; }; I think that using tag::apply instead of tag::function would make proto more consistent with other boost naming conventions, and also make it easier for others (who were familiar with mpl apply) to see that it's not surprising that "function fun is treated as if it were and *operand*". I, at first kinda agreed with Markus' assessment; however, now I see why it might be better as is. If I'd seen apply instead of function, this would have made the justification for the current form easier to see.