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

时间:2013-08-04 16:47:26

标签: c++ c++11 map lambda

尝试使用lambda覆盖map::compare函数,似乎以下解决方案有效。

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

但是,我必须首先定义cmp并稍后再使用它 我可以在没有定义'cmp'的情况下这样做吗?

3 个答案:

答案 0 :(得分:15)

不,你不能在未评估的上下文中使用lambda - 即示例中的模板参数。 所以你必须在其他地方定义它(使用auto),然后使用decltype ...反过来,因为它已经提到使用“序数”仿函数

如果您的问题是关于“如何使用lambda表达式* 一次 *定义地图时”,您可以利用lambdas的隐式转换为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类型引入别名,以便以后减少输入...

答案 1 :(得分:6)

#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比较。

答案 2 :(得分:4)

您可以执行以下操作:从传递给函数的函数中推导出地图类型。

#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

希望这有帮助!