I need to sort std::pair, the second element are different struct, ideally i would like to have a single elegant function but i could also do overloaded function, unfortunately even with overloaded functions its not compiling because of : <unresolved overloaded function type>
typedef struct{
int x, y;
} myStruct;
template <typename S> static bool comp(std::pair<int, S> pair1, std::pair<int, S> pair2){
auto val1 = std::get<int>(pair1);
auto val2 = std::get<int>(pair2);
return val1 < val2;
}
int main(){
myStruct test;
std::vector<std::pair<int, myStruct>> v {{9,test}, {2,test}, {4,test}, {3,test}, {1,test}};
std::sort(v.begin(), v.end(), comp);
}
CodePudding user response:
The main idea is OK, but there are only one problems with this code.
- The sort function MUST know the type of the functor since it cannot be deduced, so you should write:
std::sort(v.begin(), v.end(), comp<myStruct>);
in order to let your compiler know what function to "instantiate" within the Two-phase name lookup
CodePudding user response:
std::sort(v.begin(), v.end(), comp);
comp
is a name of a template. comp
is not a function, whose name evaluates to a function pointer. comp
is a template. The third parameter to std::sort
is not a template name. It's a callable object, of some kind. There are certain requirements for that callable object, but that's immaterial here.
How do you make a callable object out of a template? Instantiate this template. How do you instantiate a template? You specify what it's parameters are.
std::sort(v.begin(), v.end(), comp<myStruct>);
In many instances template parameters can be deduced, but not in this case, for rather complicated reasons.