
Thanks, Eric. That was an Ah-ha moment for me. I tried a different variation of your program. I changed point to a templated tuple<typename X, typename Y> and declared the terminals x and y with proto::_ template arguments. Here is the complete program :
I re-worked the program as below to achieve what I need. But now, using the DSEL with a new data-type becomes much more invasive, because I need some rules to the grammar. May be there is a less invasive and more elegant way? Also, I don't understand why I need both This(tuple<>&) and This(const tuple<>&) versions in the get_tuple_* classes. Removing either one of them causes a compiler error. #include <cassert> #include <boost/proto/proto.hpp> #include <iostream> namespace proto = boost::proto; template<typename X, typename Y> struct tuple { X x; Y y; }; struct arg_ {}; proto::terminal<arg_>::type arg = {{}}; struct x_ {}; proto::terminal<x_>::type x = {{}}; struct y_ {}; proto::terminal<y_>::type y = {{}}; struct get_tuple_x : proto::callable { template<typename Sig> struct result; template<typename This, typename X, typename Y> struct result<This(tuple<X, Y> &)> { typedef X type; }; template<typename This, typename X, typename Y> struct result<This(const tuple<X, Y> &)> { typedef X type; }; template<typename X, typename Y> X operator()(tuple<X, Y> &t) const { return t.x; } template<typename X, typename Y> X operator()(const tuple<X, Y> &t) const { return t.x; } }; struct get_tuple_y : proto::callable { template<typename Sig> struct result; template<typename This, typename X, typename Y> struct result<This(tuple<X, Y> &)> { typedef Y type; }; template<typename This, typename X, typename Y> struct result<This(const tuple<X, Y> &)> { typedef Y type; }; template<typename X, typename Y> Y operator()(tuple<X, Y> &t) const { return t.y; } template<typename X, typename Y> Y operator()(const tuple<X, Y> &t) const { return t.y; } }; struct micro_lambda : proto::or_< proto::when< proto::mem_ptr<proto::terminal<arg_>, proto::terminal<x_> > , get_tuple_x(proto::_state)> , proto::when< proto::mem_ptr<proto::terminal<arg_>, proto::terminal<y_> > , get_tuple_y(proto::_state)> , proto::otherwise< proto::_default<micro_lambda>
{} eval; using namespace std; int main() { tuple<int, float> t; t.x = 1; t.y = 41.f; cout << eval(arg->*x + arg->*y, t) << endl; } Manjunath