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, alpha
s in your case. beta::operator<
is never used.