On Wed, Mar 3, 2010 at 4:20 PM, Manjunath Kudlur wrote:
On Wed, Mar 3, 2010 at 4:12 PM, Eric Niebler wrote:
On 3/4/2010 6:51 AM, Manjunath Kudlur wrote:
<snip>
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?
This is a bug. Thanks for reporting it. It's now fixed on trunk.
Similar problem seems to exists for expression of the form
Program_(a)(10). Here, Program_ is a function that returns
proto::function,
proto::terminalproto::_ > >. I wrap it in program_expr, and I
define operator()(int) in that expression wrapper class. I try to set
the value of the argument passed in, but I run into the same
const-ness mismatch compiler error. Please let me know if I am missing
something. Here is the complete program: (Look for the line with //
COMPILER ERROR comment).
#include
#include
#include <iostream>
#include <sstream>
#include <string>
namespace proto=boost::proto;
namespace mpl=boost::mpl;
template<typename VT>
struct Var {
VT value;
void assign(const VT v) {
value = v;
}
};
struct program_ {};
struct _assign
: proto::callable {
typedef void result_type;
template<typename VT>
result_type operator()(Var<VT> &var) const {
var.assign(20);
}
template<typename VT>
result_type operator()(Var<VT> &var, const VT val) const {
var.assign(val);
}
};
struct assign
: proto::or_<
proto::whenproto::_ >,
_assign(proto::_value)>,
proto::whenproto::_ >,
proto::literalproto::_ >,
_assign(proto::_value(proto::_left), proto::_value(proto::_right))>,
proto::whenproto::_ >,
proto::literalproto::_ >,
_assign(proto::_value(proto::_left), proto::_value(proto::_right))>
{};
template<class E> struct program_expr;
struct program_generator
: proto::or_<
proto::when,
proto::terminalproto::_ > >,
proto::pod_generator(proto::_expr)>
{};
struct program_domain
: proto::domain
{};
template<typename A0>
typename proto::result_of::make_expr::type const
Program_(A0 const &a0)
{
return proto::make_expr(
program_(),
boost::ref(a0)
);
}
template<typename Expr>
struct program_expr {
BOOST_PROTO_BASIC_EXTENDS(Expr, program_expr<Expr>, program_domain);
BOOST_PROTO_EXTENDS_SUBSCRIPT();
typedef void result_type;
result_type operator()(int a) const {
std::cout << "program with one arg\n";
// COMPILER ERROR on this line
(proto::value(proto::child_c<1>(*this))).assign(a);
}
};
typedef proto::terminal::type int32_;
int main()
{
int32_ a,b,c;
assign()(a=20);
assign()(a(30));
Program_(a)(10);
std::cout << proto::value(a).value << std::endl;
}