
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.
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. In Christ, Steven Watanabe