
From reading the documentation, I understand that expressions and objects that are wrapped in proto::terminal<> are held by reference. In the following code, in the "assign" grammar, I match proto::terminalproto::_ > and call _assign on proto::_value. As expected, a reference to the object held in the terminal gets passed to the callable transform, and I can assign some value to it.
template<typename VT>
struct Var {
VT value;
void assign(const VT v) {
value = v;
}
};
struct _assign
: proto::callable {
typedef void result_type;
template<typename VT>
result_type operator()(Var<VT> &var) const {
var.assign(20);
}
};
struct assign
: proto::or_<
proto::when
{};
typedef proto::terminal::type int32_;
int main()
{
int32_ a,b,c;
assign()(a);
std::cout << proto::value(a).value << std::endl;
}
Now, I add the following rules to assign grammar :
struct assign
: proto::or_<
proto::when
{};
and the following operator() overload to _assign : template<typename VT> result_type operator()(Var<VT> &var, const VT val) const { var.assign(val); } I can merrily call assign()(a=10) and I get the expected behaviour. But when I call assign()(a(20)), I get a compilation error saying that there is no match for operator()(const Var<int> &, const int &). Why is that when I call proto::_value(proto::_left) on a proto::function expression, a *const* reference gets passed to the transform? Did I miss some part of the documentation where this is explained? Manjunath