2

The complete code is on https://gist.github.com/1341623

I'd like to sort an index array (or vector) for another vector, such that the array is ordered by the index of the other vector. However, the type of vector::at cannot be resolved.

I did a try as follows:

This is OK

sort(v.begin(), v.end());

I'd like to sort the indexes according to the array, but placeholders do not overload operator[]

sort(index,index+10, a[_1] < a[_2]);

However, they overload operator+ and operator*

sort(index,index+10, *(a+_1) < *(a+_2));

I'd like to sort the indexes according to the vector, but compiler cannot resolve the type of `vector::at'.

sort(index,index+10,
  bind(&(vector<int>::at), &v, _1) < bind(&(vector<int>::at), &v, _2));
// error: no matching function for call
// to ‘bind(<unresolved overloaded function type>, ...

After searching on the web, I found I have to specify the overloaded method type, but compiler still says it cannot resolve the type.

sort(index,index+10,
   bind(&static_cast<const int (*)(size_t)>(vector<int>::at), &v, _1)
 < bind(&static_cast<const int (*)(size_t)>(vector<int>::at), &v, _2));
// error: invalid static_cast from type ‘<unresolved overloaded function type>’
// to type ‘const int (*)(size_t)’ ...

I tried to get the version of vector::at I want, but the conversion seems to be failed.

vector<int>::const_reference (*vector_int_at)(vector<int>::size_type)(vector<int>::at);
sort(index,index+10,
  bind(&vector_int_at, &v, _1) < bind(&vector_int_at, &v, _2));
// error: no matches converting function ‘at’ to type ‘const int& (*)(size_t)’ ...

What can I do for this problem? Or I misunderstand something?

CrBoy
  • 43
  • 4
  • I've got the answer I expected, and update the gist post at the top. The key point is that I miss the correct type declaration of the `vector_int_at`. An C++11 solution is also put. Thanks to all. – CrBoy Nov 05 '11 at 17:00
  • Boost.Lambda is deprecated; use [Boost.Phoenix](http://www.boost.org/libs/phoenix/) instead (which btw does support `operator[]` on placeholders). – ildjarn Nov 05 '11 at 17:05

3 Answers3

2

Remember that pointers to member functions and pointers to free functions have different types. Try: vector<int>::const_reference (vector<int>::*vector_int_at)(vector<int>::size_type) const = &vector<int>::at;

aschepler
  • 70,891
  • 9
  • 107
  • 161
1

I usually just declare a forwarding function to avoid the various cans of worm associated with this sort of thing:

int vector_at(vector<int> const * v, size_t index) { return v->at(index); }

...

sort(index, index+10, bind(vector_at, &v, _1) < bind(vector_at, &v, _2));
Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • Yes I know about this. It's just like defining a functor. However, I want if there's a solution not to define a function/functor somewhere else. :) – CrBoy Nov 05 '11 at 15:30
  • For functions in the standard library it's not technically safe to do so - `vector::at` may have multiple overloads, or extra default parameters. (Although in this case it's reasonably unlikely.) Also, it's a lot less ugly and painful like this! – Alan Stokes Nov 05 '11 at 15:48
1

Any reason why you do not use a lambda?

sort(index, index+10, [&a](int i, int j) { return a[i] < a[j]; });
Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85