Home > database >  Change the comparator for a map that is defined by a variadic template
Change the comparator for a map that is defined by a variadic template

Time:12-02

I have the following piece of code,

// Type your code here, or load an example.
#include <string>
#include <map>
#include <iostream>

struct alpha{
    alpha() = default;
    alpha(std::string str, int i ) : mystr(str), num(i){}
    std::string mystr{"abc"};
    int num{0};
    bool operator <( const alpha &al ) const
    {
       return ( mystr < al.mystr );
    }
};
struct beta{
    beta() = default;
    beta(std::string str, int i ) : mystr(str), num(i){}
    std::string mystr{"abc"};
    int num{0};
    bool operator <( const beta &b1 ) const
    {
       return ( mystr < b1.mystr );
    }

};

template<template<typename ...> class Tcont, typename... Titem>
struct label_str
{
    Tcont<Titem...> kindA;
};

struct Label_map
{
    label_str<std::map, alpha, beta> al_beta_map;
};

struct big_map
{
    Label_map first;
    Label_map second;
};

int main()
{
    auto a1 = alpha("a1", 1);
    auto a2 = alpha("a2", 2);
    auto a3 = alpha("a3", 3);
    auto a4 = alpha("a4", 4);
    auto a5 = alpha("a5", 5);

    auto b1 = beta("b1", 1);
    auto b2 = beta("b2", 2);
    auto b3 = beta("b3", 3);
    auto b4 = beta("b4", 4);
    auto b5 = beta("b5", 5);

    big_map bigg;

    auto &first_map = bigg.first;
    auto &second_map = bigg.second;

    first_map.al_beta_map.kindA[a5] =  b5;
    first_map.al_beta_map.kindA[a2] =  b2;
    first_map.al_beta_map.kindA[a3] =  b3;
    first_map.al_beta_map.kindA[a4] =  b4;
    first_map.al_beta_map.kindA[a1] =  b1;
    auto &mmmap = first_map.al_beta_map.kindA;
    for ( auto [p,_] : mmmap ) 
        std::cout << "( " << p.mystr << ", " << p.num << " )" << std::endl;
}

I want to change the comaparator for alpha and beta to num instead of mystr. I understand that I have to write a custom lambda to compare but I am not sure because of the variadic templates. Assuming I do not have access to change the alpha and beta, how do I do this?

godbolt like is here Link

CodePudding user response:

Type of the custom comparator must be passed to std::map as the third argument, you can actually use the variadic label_str to your advantage there:

struct num_comparator {
    template <typename T>
    bool operator()(const T &l, const T &r) const {
        return (l.num < r.num);
    }
};
struct Label_map {
    label_str<std::map, alpha, beta, num_comparator> al_beta_map;
};

One could use a lambda but the hassle with it is the lambdas are not default constructible until C 20, meaning just std::map<alpha, beta,decltype(global_lambda)> is not enough, you have to explicitly pass it in the ctor too. That could be done in your case but I see struct simpler.

Just note that std::map only ever compares it's keys, alphas in your case. beta::operator< is never used.

  • Related