0

I am trying to sort a vector below using boost::phoenix library. The class Foo has a member function 'int getvalue()'. The purpose is to sort the vector using the value returned by 'getvalue()'. But something is missing. I get compiler error as '::second is not a class or namespace'

      std::vector<std::pair<int, Foo> > fooVec;

      boost::phoenix::sort ( boost::phoenix::bind( &std::pair<int, Foo>::second::getvalue(), boost::phoenix::arg_names::arg1) (*fooVec.begin() ), std::less<int>() );

Can anybody please explain this. What changes do I need to make this work?

Thanks.

PS: I know I could have used function object/lambda or soemthing similar but I wanted to try out boost::phoenix.

polapts
  • 5,493
  • 10
  • 37
  • 49
  • I don't think that this will sort your vector. The first param has to be the range that will be sorted. Since you make a phoenix expression out of it your vector won't be changed. – mkaes Nov 08 '11 at 15:14
  • Could you be so kind to tell me the correct way to do it. Thanks... – polapts Nov 08 '11 at 15:25
  • I added a answer with an example how I would use phoenix in this case. But it differs from your approach since I cannot use std::less anymore. But maybe it helps. – mkaes Nov 08 '11 at 15:31

2 Answers2

2

It's just what the error message says. std::pair<int, Foo>::second is a data member, not a class or namespace, so you cannot use operator :: on it.

Instead of second, you can use second_type, which is a typedef for the type of the second element in the pair:

boost::phoenix::sort ( boost::phoenix::bind( &std::pair<int, Foo>::second_type::getvalue, boost::phoenix::arg_names::arg1) (*fooVec.begin() ), std::less<int>() );
Gorpik
  • 10,940
  • 4
  • 36
  • 56
  • Thanks for the answer but unfortunately it does not work. I get the same error. error: ‘getvalue’ is not a member of ‘std::pair::second_type’ – polapts Nov 08 '11 at 15:23
  • This means that class `Foo` has no method called `getvalue()`. Of course, I don't know what are the members of that class, but I hope you do. – Gorpik Nov 08 '11 at 15:30
  • Oh, sorry, you have to remove the `()` (to get a pointer to a function, use just its name, don't call it). Answer edited again. – Gorpik Nov 08 '11 at 15:33
  • Still does not work. error: ‘getvalue’ is not a member of ‘std::pair::second_type’ – polapts Nov 08 '11 at 15:45
  • Then you'd probably need a `typename` before `std::pair::second_type`. Anyway, since mkaes's answer solved your problem, I don't think it's worth to keep beating the bush. – Gorpik Nov 11 '11 at 09:10
2

As commented, I don't think that your way of creating a phoenix actor from your vector can be used to sort it, but I never used the algorithms from phoenix so I not sure about it. You can of course use sort and create a functor with phoenix to sort it.
So I would suggest to use phoenix this way.

boost::phoenix::sort(boost::phoenix::placeholders::arg1, boost::phoenix::placeholders::arg2)(fooVec, 
        boost::phoenix::bind( &Foo::getvalue, boost::phoenix::bind( &std::pair<int, Foo>::second, boost::phoenix::placeholders::arg1)) < boost::phoenix::bind( &Foo::getvalue, boost::phoenix::bind( &std::pair<int, Foo>::second, boost::phoenix::placeholders::arg2))
        );
mkaes
  • 13,781
  • 10
  • 52
  • 72
  • using boost::phoenix::sort; using boost::phoenix::arg_names::arg1; int array[] = {3,1,2}; std::list test_list(array, array + 3); boost::phoenix::sort(arg1, std::greater())(test_list); This is the example that comes as reference with boost::phoenix library. I was following it. Thanks for your answer though. – polapts Nov 08 '11 at 15:51
  • @Pavan: This exactly what I mean. They pass in the container as a first argument. You pass in a phoenix expression as the first param. That won't sort your container. – mkaes Nov 08 '11 at 16:18