覆盖map::直接与lambda函数比较

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

尝试使用 lambda 覆盖

map::compare
函数,似乎以下解决方案有效。

auto cmp = [](const int&a, const int& b) { return a < b; };
std::map<int, int, decltype(cmp)> myMap(cmp);

但是,我必须先定义

cmp
,然后再使用它。
我可以在不定义“cmp”的情况下执行此操作吗?

c++ c++11 dictionary lambda
4个回答
26
投票

不,你不能在未评估的上下文中使用 lambda —— 即示例中的模板参数。 所以你必须在其他地方定义它(使用

auto
),然后使用
decltype
...另一种方式,正如已经提到的那样,是使用“序数”函子

如果您的问题是关于“如何在定义映射时使用 lambda 表达式 *once*”,您可以利用 lambda 到 std::function

 的隐式转换,如下所示:

#include <iostream> #include <functional> #include <map> int main() { auto m = std::map<int, int, std::function<bool(const int&, const int&)>>{ [](const int& a, const int& b) { return a < b; } }; return 0; }

您可以为该

map

 类型引入别名,以减少以后的输入...


8
投票
#include <iostream> #include <functional> #include <map> #include <typeinfo> typedef std::map< int, int, std::function<bool(const int&, const int&)> > MyMap; int main() { auto cmp = [](const int& a, const int& b) { return a < b; }; MyMap map(cmp); return 0; }

使用

std::function

 为比较器类型提供适当的类型签名,您可以定义映射类型,然后分配您想要的任何 lambda 比较。


5
投票
您可以执行类似的操作,其中映射的类型是从您传递给函数的函数推导出来的。

#include <map> template<class Key, class Value, class F> std::map<Key, Value, F> make_map(const F& f) { return std::map<Key, Value, F>{f}; } int main() { auto my_map = make_map<int, int>([](const int&a, const int& b) { return a < b; }); my_map[10] = 20; }

我没有看到这样做的太多理由,但我不会说这是无用的。通常,您需要一个已知的比较器,以便可以轻松传递地图。通过上面的设置,您可以一直使用模板函数,如下所示

tempalte<class F> void do_somthing(const std::map<int, int, F>& m) { }

这不一定是坏事,但我的直觉告诉我,拥有一种只能由泛型函数处理的类型是不好的。我认为它对于 lambda 函数来说效果很好,但仅此而已。这里的解决方案是使用 std::function

#include <map> #include <functional> template<class Key, class Value> using my_map_t = std::map<Key, Value, std::function<bool(const Key&, const Key&)>>; int main() { my_map_t<int, int> my_map{[](const int&a, const int& b) { return a < b; }}; my_map[10] = 20; }

现在您可以使用任何您想要的谓词,并且您有一个可以使用的具体类型,my_map

希望这有帮助!


2
投票

C++20:

如果没有指定捕获,闭包类型有一个默认的default 构造函数。

因此你可以做到

这个

std::map<int, int, decltype([](const int&a, const int& b) { return a < b; })> myMap; int main() { myMap.insert({7, 1}); myMap.insert({46, 2}); myMap.insert({56, 3}); for (const auto& [key,value]:myMap) { std::cout << key << " " << value << std::endl; } }
    
© www.soinside.com 2019 - 2024. All rights reserved.