Have a look at the lazy vector example from Proto's docs. There is a lazy_vector_expr
template for lazy vector expressions, and a lazy_vector
template specifically for terminals (which inherits most of its implementation from lazy_vector_expr
). lazy_vector
defines a +=
operator that accepts arbitrary lazy-vector expressions, evaluates them, and stores the result.
It sounds to me like you're doing something similar. But instead of +=
, you are looking for ordinary assignment and converting construction. So define a template'd constructor and assignment operator. Something like (untested)...
template<typename XXX = proto::is_proto_expr> // hack, needed to for ADL
struct replaced_type_t
: MyDoubleExpr< proto::terminal<double>::type >
{
replaced_type_t(double d = 0.0)
: MyDoubleExpr< proto::terminal<double>::type >(
proto::terminal<double>::type::make(d)
)
{}
// Converting constructor
template<typename OtherExpr>
replaced_type_t(MyDoubleExpr<OtherExpr> const & e)
{
// Evaluate e, assign to *this
}
// Converting assignment
template<typename OtherExpr>
replaced_type_t& operator=(MyDoubleExpr<OtherExpr> const & e)
{
// Evaluate e, assign to *this
}
};
typedef replaced_type_t<> replaced_type;
Incidentally, when you used BOOST_PROTO_EXTENDS_USING_ASSIGN
, what you got was an overloaded assignment operator that building a bigger expression. So this:
replaced_type c;
c = (a + b) * 2.0;
... is going to have the unexciting effect of creating a temporary MyDoubleExpr<>
containing an assignment node, and then throwing it away.
HTH!