creating unordered_set with lambda
creating unordered_set with lambda
如何用lambda生成unordered_set
?(我知道如何使用用户定义的哈希结构和operator==
)
我当前的代码是:
#include <unordered_set>
#include <functional>
struct Point
{
float x;
float y;
Point() : x(0), y(0) {}
};
int main()
{
auto hash=[](const Point& pt){
return (size_t)(pt.x*100 + pt.y);
};
auto hashFunc=[&hash](){
return std::function<size_t(const Point&)> (hash);
};
auto equal=[](const Point& pt1, const Point& pt2){
return ((pt1.x == pt2.x) && (pt1.y == pt2.y));
};
auto equalFunc=[&equal](){
return std::function<size_t(const Point&,const Point&)> (equal);
};
using PointHash=std::unordered_set<Point,decltype(hashFunc),decltype(equalFunc)>;
PointHash Test(10,hashFunc,equalFunc);
return 0;
}
它给我几个!错误数(live):
请注意,我为返回std::function
(equalFunc
, hashFunc
)做了一个lambda,因为似乎在unordered_set
中,一些函数试图复制该lambda的返回类型!
也很奇怪,gcc 4.8编译的代码很好!(live)
您的代码中不需要std::function
抽象。直接通过decltype
为unordered_set
的模板参数获取lambda类型
auto hash=[](const Point& pt){
return (size_t)(pt.x*100 + pt.y);
};
auto equal=[](const Point& pt1, const Point& pt2){
return ((pt1.x == pt2.x) && (pt1.y == pt2.y));
};
using PointHash = std::unordered_set<Point, decltype(hash), decltype(equal)>;
PointHash Test(10, hash, equal);
在你只是执行两个结构体的元素明智比较的地方,我发现使用std::tie
代替
auto equal=[](const Point& pt1, const Point& pt2){
return std::tie(pt1.x, pt1.y) == std::tie(pt2.x, pt2.y);
};
上面的代码可以在gcc和clang上编译,但是由于这个bug不能在VS2013上编译。VS标准库实现试图在某个地方默认构造lambda类型,这将会失败,因为默认构造函数被删除了。std::function
可以用作VS2013的变通方法,但我坚持用重载的operator()
来定义struct
。
#include <vector>
#include <unordered_set>
#include <functional>
struct Point
{
float x;
float y;
Point() : x(0), y(0) {}
};
int main()
{
auto hash = [](const Point& pt){
return (size_t)(pt.x*100 + pt.y);
};
using hashFunc = std::function<size_t(const Point&)>;
auto equal = [](const Point& pt1, const Point& pt2){
return ((pt1.x == pt2.x) && (pt1.y == pt2.y));
};
using equalFunc = std::function<size_t(const Point&,const Point&)>;
using PointHash = std::unordered_set<Point,hashFunc,equalFunc>;
PointHash Test(10, hash, equal);
return 0;
}
您根本不需要hashFunc
和equalFunc
,只需使用lambdas:
auto hash = [](const Point& pt){ return (size_t)(pt.x*100 + pt.y); };
auto equal = [](const Point& pt1, const Point& pt2) {return ((pt1.x == pt2.x) && (pt1.y == pt2.y)); };
using PointHash=std::unordered_set<Point,decltype(hash),decltype(equal)>;
PointHash Test(10,hash,equal);
现场演示
这不会编译hashFunc
和equalFunc
捕获 lambdas。带有捕获子句的Lambdas没有隐式转换为指针到函数类型。正如您从其他答案中看到的那样,您需要某种方法来摆脱捕获子句,这就像直接使用hash
和equal
一样简单。
似乎VS不能编译新的代码。或者,您可以使用自由函数代替lambdas,并用函数指针类型的别名替换decltype(...)
:
std::size_t hash(const Point& pt)
{
return pt.x * 100 + pt.y;
}
bool equal(const Point& pt1, const Point& pt2)
{
return ((pt1.x == pt2.x) && (pt1.y == pt2.y));
}
int main()
{
using hash_type = std::size_t (*)(const Point&);
using equal_type = bool (*)(const Point&, const Point&);
using PointHash = std::unordered_set<Point, hash_type, equal_type>;
PointHash Test(10, hash, equal);
}
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- Problems with std::cin.fail()
- Pybind11: init<> with lambda
- C++, Fulfilling typedef with lambda?
- 在 lambda(parameter) 中为 std::transform with std::sregex_token
- std::function std::bind with lambda overload ambiguity
- std::max with lambda and auto
- std::make_unique<std::thread> with lambda
- Using boost::lambda with boost::thread
- QtConcurrent::run with lambda on mac os 没有提供匹配函数
- 如何使用 std::bind with lambda
- creating unordered_set with lambda
- ptr_fun with a lambda function
- c++ lambda with捕获作为函数指针
- EXC_BAD_ACCESS with lambda capture
- Std::transform with lambda:跳过一些项
- Max_element with lambda:如何编译