
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_g... 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