Because Boost.YAP operates on Expressions, it is possible to mix and match Expressions that are instantiations of different templates.
Here's why that's important. Say we have two types in a library. S is a string type, and M
is a matrix type. In the code here, s
and m are objects of types
S and M
respectively. Say we also have typical operator overloads for these types,
so m *
m and s[0]
are well-formed expressions, but m[0]
and s *
s are not.
To use these with Boost.YAP I might write an expression template for each:
template <...> struct m_expr { // ... }; BOOST_YAP_USER_BINARY_OPERATOR(times, m_expr, m_expr) template <...> struct s_expr { // ... BOOST_YAP_USER_SUBSCRIPT_OPERATOR(::s_expr) };
With this, I might write a Boost.YAP expression like:
some_expr_producing_func(S("my_matrix")) * some_matrix
I can transform this expression however I like, and do not have to worry about the fact that it contains expressions instantiated from different templates.
If Boost.YAP required an expression to be instantiated from a single expression
template expr<>,
expr<>
would have to have both operators. This means that all of a sudden s * s
and m[0] would be
well-formed expressions within a Boost.YAP expression, but not
for the real types S and
M respectively. That would
be super weird.