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.