
Larry Evans wrote:
On 05/19/08 18:51, Eric Niebler wrote:
Um, does this mean you're using the proto/v4 branch?
Yes.
Are you still having problems, or have they gone away?
They're still there.
Can you send a compiler error and steps to repro? 'Cause it works over here.
The attachment on 1st post has '#if 1' around line 117. That should produce the error. The 2nd post's attachment has '#if 0' and doesn't produce an error. When you run, do you use '#if 1' or not?
The complete bjam output of 2nd post's attachment with '#if 1' is attached as bjam.out.
Ah, you're using gcc. I see the error now. I'm sorry to say this behavior is by-design -- at least until we get rvalue references -- although there are simple work-arounds. Let me explain. A Proto transform takes an expression tree as its first argument. The signature is something like this: // take expr, state and data by non-const ref template<class Expr, class State, class Data> typename result<void(Expr &, State &, Data &)>::type operator()(Expr &expr, State &state, Data &data) const // an overload for a const state parameter. template<class Expr, class State, class Data> typename result<void(Expr &, State const &, Data &)>::type operator()(Expr &expr, State const &state, Data &data) const Note that expressions are taken by non-const reference. They must be lvalues or const-qualified rvalues. That's usually the case, but not for your code. (The data parameter is handled similarly, but there are other overloads so you don't have to specify it.) You might think I could just add an overload that takes an expression by const reference to solve the problem. But that introduces another. To do overload resolution, the compiler would need to calculate the return type for both overloads, and for some expressions, the return type calculation will fail if the expression is const-qualified. (A transform could mutate an expression tree in-place. The expression tree had better not be const.) So even if you never actually pass a const expression tree, the mere presence of the overload will cause the compile to fail. Very frustrating. So that's the reason why. You can work around the error by making sure you pass only lvalue expression trees or const-qualified rvalue expression trees to transforms. You can do that by converting a non-const rvalue into a const lvalue by passing it through a dummy as_lvalue() function like: template<class T> T const & as_lvalue(T const &t) { return t; } When I do that, I hit another error in your code having to do with an ambiguous conversion sequence. Doesn't look like a Proto problem, though. HTH, -- Eric Niebler Boost Consulting www.boost-consulting.com