尝试使用 lambda 覆盖
map::compare
函数,似乎以下解决方案有效。
auto cmp = [](const int&a, const int& b) { return a < b; };
std::map<int, int, decltype(cmp)> myMap(cmp);
但是,我必须先定义
cmp
,然后再使用它。不,你不能在未评估的上下文中使用 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
类型引入别名,以减少以后的输入...
#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 比较。
#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
希望这有帮助!
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;
}
}