无缝使用具有不同比较器的地图

问题描述 投票:0回答:1

我使用别名来引用两张地图之一:

map<int, int> & map_alias = use_map_a ? map_a : map_b;

但随后更改

map_b
以使用
std::greater
作为比较器(而不是默认的
std::less
)。

正如预期的那样,这行代码不再起作用,因为map_alias/map_a/map_b 并不都是同一类型。 是否有一些简单的解决方法可以允许继续使用别名(或类似且简单的方法)? 我只是希望后续代码能够通用地运行,而不需要知道它在两个地图中的哪一个上运行,并且不需要构建一个巨大的伞式基础设施来实现它。

使用

union
/
tuple
/
variant
/
std::any
并不能真正解决任何问题,因为仍然需要知道地图类型才能从这些对象访问地图。

限制:我使用的是 C++14,因此 constexpr 不能在解决方案中使用。 除非必要,否则最好不必使用 SFINAE。 而且我也无法获得提升。

我花了几个小时寻找解决方案,所以提前致谢!

c++ templates stl c++14 alias
1个回答
0
投票

您可以通过构造函数而不是模板参数传递比较器来将它们变成一种类型:

std::map<int, int, std::function<bool(int, int)>> map_a{std::less<int>{}};
std::map<int, int, std::function<bool(int, int)>> map_b{std::greater<int>{}};
bool use_map_a = true;
auto& map_alias = use_map_a ? map_a : map_b;

std::function
有点昂贵,因为它在内部必须键入擦除所有可调用类型。您可以使用函数指针,但为此您不能使用
std::less
std::greater
:

bool myLess(int a, int b) {
    return a < b;
}
std::map<int, int, bool(*)(int, int)> map_a{myLess};

//or with lambda
std::map<int, int, bool(*)(int, int)> map_b{[](int a, int b){return a > b;}};

© www.soinside.com 2019 - 2024. All rights reserved.