Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

map choose `std::greater` or `std::less` at runtime

Tags:

c++

This line:

std::map<long int, long int, std::greater<long int>> current_book;

I would like to replace it by the logical equivalent of:

int Side = ...
if (Side == 1){
    std::map<long int, long int, std::greater<long int>> current_book;
} else {
    std::map<long int, long int, std::less<long int>> current_book;
}
like image 268
user189035 Avatar asked Nov 23 '18 19:11

user189035


People also ask

What is map in C++ with example?

(since C++17) std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare. Search, removal, and insertion operations have logarithmic complexity.

What is the use of greater in C++?

std::greater in C++ with Examples. The std::greater is a functional object which is used for performing comparisons. It is defined as a Function object class for the greater-than inequality comparison. This can be used for changing the functionality of the given function.

Which algorithms can be used with the STL?

This can also be used with various standard algorithms such as sort, priority queue, etc. Want to learn from the best curated videos and practice problems, check out the C++ Foundation Course for Basic to Advanced C++ and C++ STL Course for foundation plus STL.


3 Answers

You can use std::function for that:

using mymap = std::map<long,long,std::function<bool(long,long)>>;
auto m = Side ? mymap( std::less<long>() ) : mymap( std::greater<long>() );

live example

like image 68
Slava Avatar answered Oct 07 '22 05:10

Slava


You have to implement a custom comparator class, something along the lines of:

class map_comparator {

   bool less_than;

public:

   map_comparator(bool less_than) : less_than{less_than} {}

   bool operator()(long a, long b) const
   {
       if (less_than)
             return a < b;
       return a > b;
   }
};

And then use it to construct your map, using the constructor that takes an instance of the comparator class as a parameter, and then pass in the appropriately constructed comparator class instance:

std::map<long int, long int, map_comparator>
     current_book{ map_comparator{ Side != 1}};
like image 29
Sam Varshavchik Avatar answered Oct 07 '22 04:10

Sam Varshavchik


You can use a straight function pointer. This approach won't suffer from overhead of if (less_than) branching on each comparison or from overhead of std::function:

#include <map>

using t_Key = long int;
using t_Value = long int;
using t_Comparator = bool ( * )(t_Key const left, t_Key const right);
using t_Map = ::std::map<t_Key, t_Value, t_Comparator>;

bool Is_Less(t_Key const left, t_Key const right)
{
    return left < right;
}

bool Is_Greater(t_Key const left, t_Key const right)
{
    return left > right;
}

int main()
{
    int Side{};
    t_Map current_book{(Side == 1) ? &Is_Less : &Is_Greater};
    return 0;
}
like image 28
user7860670 Avatar answered Oct 07 '22 05:10

user7860670