2

Look at this example (from cppreference):

#include <algorithm>
#include <vector>
#include <iostream>

 struct S
 {
     int number;
     char name;
     // note: name is ignored by this comparison operator
     bool operator< ( const S& s ) const { return number < s.number; }
 };

 int main()
 {
     // note: not ordered, only partitioned w.r.t. S defined below
     const std::vector<S> vec = { {1,'A'}, {2,'B'}, {2,'C'}, {2,'D'}, {4,'G'}, {3,'F'} };

     std::cout << "\n" "Using heterogeneous comparison: ";
     struct Comp
     {
         bool operator() ( const S& s, int i ) const { return s.number < i; }
         bool operator() ( int i, const S& s ) const { return i < s.number; }
     };

     const auto p2 = std::equal_range(vec.begin(),vec.end(), 2, Comp{});

     for ( auto i = p2.first; i != p2.second; ++i )
         std::cout << i->name << ' ';
 }

Is there any need to overload operator () in 2 ways as below for a functor if I want to use the structure in std::equal_range?

PS: This is a follow up question of this one How equal_range is making use of heterogeneous comparison?, where apparently there was too many questions in one, hence I split it up to ask only for the two overloads here.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Test
  • 564
  • 3
  • 12

2 Answers2

2

From cppreference about std::equal_range:

Returns a range containing all elements equivalent to value in the range [first, last).

Equivalence between a and b is determined by !comp(a,b) && !comp(b,a).

Hence, both variants are needed when the value is an int and differs from the type of the elements in the range. Note that if S had a converting constructor from int or some S{value,dummy_char} would be passed to std::equal_range as value then the comparator wouldn't be needed in the first place, but the default comparison via < could be used.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I think I am still struggling to understand that why I had to pass a r-value as the 4th argument in equal_range. And how does I used the functor nature of the Struct comp which I never seem to have invoked. Usually when I have a functor then I first save it's state and then invoke with () – Test Jan 14 '22 at 13:53
  • @Test you don't *have to* pass an r-value. Why do you think so? You can do `auto comp = Comp{}; const auto p2 = std::equal_range(vec.begin(),vec.end(), 2, comp);` as well. The comparator isn't called by you but by the algorithm – 463035818_is_not_an_ai Jan 14 '22 at 18:55
1

Quoted from cppreference:

The signature of the predicate function should be equivalent to the following:

bool pred(const Type1 &a, const Type2 &b);

While the signature does not need to have const &, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) Type1 and Type2 regardless of value category (thus, Type1 & is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11)). The types Type1 and Type2 must be such that an object of type T can be implicitly converted to both Type1 and Type2, and an object of type ForwardIt can be dereferenced and then implicitly converted to both Type1 and Type2.

So as long as your types fulfill these requirements, one function is all that is needed.

eike
  • 1,314
  • 7
  • 18
  • So in the other link of this question, do you see any compelling reason to have the 2 overloads? I have copied it from cppreference for equal_range itself. – Test Jan 14 '22 at 12:30
  • @Test Please include all the relevant information in this question. – eike Jan 14 '22 at 12:30
  • i have already provided a link to other question. Infact in other link I was asked to split the question and hence I created this one. – Test Jan 14 '22 at 12:33
  • @Test and when you split the question as suggested, you should include all relevant information for that part of the question. If this question cannot be answered without looking at the original one, you are missing something. – eike Jan 14 '22 at 12:34
  • I am not sure what are you saying. I have already given a hyperlink to the parent question in this question description. Also this question has proper context. If I paste the entire text of other question here then both links will become same question. – Test Jan 14 '22 at 12:36
  • @Test Questions should not depend on other questions. You should include every detail that is relevant here and remove the link to the old question. – eike Jan 14 '22 at 12:38
  • this question doesn't depend on anything else. It's complete in itself. – Test Jan 14 '22 at 12:39
  • @Test no it isnt. I was a little confused myself at first, because in the code you included here there is no reason to have two overloads. Only if you pass an `int` as `value` to the algorithm the question makes sense. Anyhow, its a requirement to post a [mcve] and resisting to do so never did any good – 463035818_is_not_an_ai Jan 14 '22 at 12:40
  • @Test now I am confused again. Why did you remove the link? Now it is impossible to make sense of this question – 463035818_is_not_an_ai Jan 14 '22 at 12:41
  • @Test just include the main function of your original question in this one. – eike Jan 14 '22 at 12:42
  • @463035818_is_not_a_number - I think I am dealing with different perspective. In other question, some one asked me to split the question and hence I did. But seems here I am asked to give full information which I already gave In other and still was asked to split. – Test Jan 14 '22 at 12:42
  • @Test they asked you to split the question, not to split the code. The full [mcve] is needed. WIthout it your question makes no sense. As it stands now, the answer is: "It isnt needed, or maybe it is. We cannot know without seeing the call to the algorithm" – 463035818_is_not_an_ai Jan 14 '22 at 12:43
  • 1
    @Test You have multiple questions, all of them depend on the same information. What was asked of you in the other question was basically to ask your three different questions separately, but providing your complete code every time. – eike Jan 14 '22 at 12:43
  • 1
    @Test maybe the misunderstanding is that the complaint on the other question was not due to too much code. It is ok to post the same code more than once and ask more than one question about the same code, but it should be seperate questions (because multiple questions in one is problematic) – 463035818_is_not_an_ai Jan 14 '22 at 12:44