2

I'd like to provide an API which accepts a user-defined Boost Phoenix lambda. Unlike a C++11 lambda, a Phoenix lambda is polymorphic.

I am able to use the [] operator of a lambda argument. The following snippet will output the first element of array arr:

int arr[4] = {1,2,3,4};
cout << _1[_2](arr,0) << endl;

How can I allow the user to access member data or methods of a lambda argument? The following code snippet, for example, fails to compile; giving: error: ‘const type’ has no member named ‘x’

struct vec2 { float x,y; };
vec2 v2{1,2};
cout << ((_1).x)(v2) << endl;
user2023370
  • 10,488
  • 6
  • 50
  • 83
  • 1
    Try `((&_1)->*&vec2::x)(v2)`. – Luc Danton Feb 23 '13 at 22:52
  • Thanks, that's very helpful. I must admit though, thinking of the end user, I was hoping for something easier on the eye. – user2023370 Feb 23 '13 at 23:22
  • Is there no way even `static_cast_` might help? Alas it gives a similar error with `static_cast_(_1).x`. – user2023370 Feb 23 '13 at 23:25
  • 2
    It cannot help, no. You can write an `x` such that `x(_1)` means 'a functor which fetches the `x` member of its first parameter'. See documentation on how to write functors. – Luc Danton Feb 23 '13 at 23:28
  • Thanks again. It's good to look at that solution, but it only makes me run back to your first. I certainly wouldn't choose to ask the user to create a function object for each member access. – user2023370 Feb 24 '13 at 09:34
  • 1
    You can also use `phx::bind(&vec2::x,_1)(v2)` that is IMHO slightly less ugly (but only slightly). If you want a general solution where you can use arbitrary structs I believe you are out of luck. If you want only several specific structs, you could consider doing something similar to [this](http://www.boost.org/libs/phoenix/example/container_actor.cpp)(explained [here](http://www.boost.org/libs/phoenix/doc/html/phoenix/examples/extending_actors.html)). –  Feb 24 '13 at 10:24
  • Thanks for the links @llonesmiz; and yes, it is just slightly less ugly :) – user2023370 Feb 24 '13 at 12:37
  • 1
    I've noticed that the example I linked above doesn't compile (at least not on 1.53.0). Changing `phoenix::expression::function` to `phoenix::detail::expression::function_eval` in the return types of the member functions apparently makes it work. –  Feb 25 '13 at 14:11

0 Answers0