我可以在 boost::multi_index 类哈希接口中使用 lambda 作为哈希函数吗?
Can I use lambda as a hashing function in boost::multi_index hash-like interface?
是否可以在 boost::multi_index 的 hashed_<non>_unique 接口中使用 lambda 进行散列?
看这个例子:https://godbolt.org/z/1voof3
我也看到了这个:How to use lambda function as hash function in unordered_map? 答案是:
You need to pass lambda object to unordered_map constructor since lambda types are not default constructible.
而且我不确定是否可以在 godbolt 上对给定的示例进行操作。
我认为你做不到。使用标准容器,您将不得不向构造函数提供实际实例。但是,MultiIndex 负担不起:
As explained in the index concepts section, indices do not have public constructors or destructors. Assignment, on the other hand, is provided. Upon construction, max_load_factor() is 1.0.
漏洞?
您或许可以使用本地定义的 class:
auto const hash_f = [](int const& n) { return std::hash<int>()(n); };
struct HashType : decltype(hash_f) {};
using AnimalsMultiIndex = multi_index_container<
Animal, indexed_by<hashed_non_unique<
tag<animal_legs>, member<Animal, LegsType, &Animal::legs>,
HashType>>>;
AnimalsMultiIndex animals;
哪个有效:c++20 required
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index_container.hpp>
#include <iostream>
#include <string>
using namespace boost::multi_index;
using LegsType = int;
struct Animal {
std::string name;
LegsType legs;
};
// tags
struct animal_legs {};
int main() {
// using lambda doesn't work for hashing
auto const hash_f = [](int const& n) { return std::hash<int>()(n); };
struct HashType : decltype(hash_f) {};
using AnimalsMultiIndex = multi_index_container<
Animal, indexed_by<hashed_non_unique<
tag<animal_legs>, member<Animal, LegsType, &Animal::legs>,
HashType>>>;
AnimalsMultiIndex animals;
animals.insert({ "cat", 4 });
auto const& legs_index = animals.get<animal_legs>();
int num_of_legs = 4;
std::cout << "Number of animals that have " << num_of_legs
<< " legs is: " << legs_index.count(num_of_legs) << '\n';
}
版画
Number of animals that have 4 legs is: 1
从 C++20 开始,是的,您可以:https://godbolt.org/z/fTbzPP(注意 f
声明为 auto const hash_f
,没有 &
)。
至于@sehe 声称 multi_index_container
s 不能在构造时传递散列对象(或其他干预函数对象)的实例,这种说法是不正确的:它们可以,尽管接口有点复杂:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <functional>
struct non_default_ctble_hash
{
non_default_ctble_hash(std::size_t n):n{n}{}
template<typename T>
std::size_t operator()(const T& x){return std::hash<T>{}(x)*n;}
std::size_t n;
};
using namespace boost::multi_index;
using container=multi_index_container<
int,
indexed_by<
hashed_unique<identity<int>,non_default_ctble_hash>
>
>;
int main()
{
container::ctor_args_list cal{
{0,identity<int>{},non_default_ctble_hash{666},std::equal_to<int>{}}
};
container c(cal);
}
是否可以在 boost::multi_index 的 hashed_<non>_unique 接口中使用 lambda 进行散列? 看这个例子:https://godbolt.org/z/1voof3
我也看到了这个:How to use lambda function as hash function in unordered_map? 答案是:
You need to pass lambda object to unordered_map constructor since lambda types are not default constructible.
而且我不确定是否可以在 godbolt 上对给定的示例进行操作。
我认为你做不到。使用标准容器,您将不得不向构造函数提供实际实例。但是,MultiIndex 负担不起:
As explained in the index concepts section, indices do not have public constructors or destructors. Assignment, on the other hand, is provided. Upon construction, max_load_factor() is 1.0.
漏洞?
您或许可以使用本地定义的 class:
auto const hash_f = [](int const& n) { return std::hash<int>()(n); };
struct HashType : decltype(hash_f) {};
using AnimalsMultiIndex = multi_index_container<
Animal, indexed_by<hashed_non_unique<
tag<animal_legs>, member<Animal, LegsType, &Animal::legs>,
HashType>>>;
AnimalsMultiIndex animals;
哪个有效:c++20 required
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index_container.hpp>
#include <iostream>
#include <string>
using namespace boost::multi_index;
using LegsType = int;
struct Animal {
std::string name;
LegsType legs;
};
// tags
struct animal_legs {};
int main() {
// using lambda doesn't work for hashing
auto const hash_f = [](int const& n) { return std::hash<int>()(n); };
struct HashType : decltype(hash_f) {};
using AnimalsMultiIndex = multi_index_container<
Animal, indexed_by<hashed_non_unique<
tag<animal_legs>, member<Animal, LegsType, &Animal::legs>,
HashType>>>;
AnimalsMultiIndex animals;
animals.insert({ "cat", 4 });
auto const& legs_index = animals.get<animal_legs>();
int num_of_legs = 4;
std::cout << "Number of animals that have " << num_of_legs
<< " legs is: " << legs_index.count(num_of_legs) << '\n';
}
版画
Number of animals that have 4 legs is: 1
从 C++20 开始,是的,您可以:https://godbolt.org/z/fTbzPP(注意 f
声明为 auto const hash_f
,没有 &
)。
至于@sehe 声称 multi_index_container
s 不能在构造时传递散列对象(或其他干预函数对象)的实例,这种说法是不正确的:它们可以,尽管接口有点复杂:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <functional>
struct non_default_ctble_hash
{
non_default_ctble_hash(std::size_t n):n{n}{}
template<typename T>
std::size_t operator()(const T& x){return std::hash<T>{}(x)*n;}
std::size_t n;
};
using namespace boost::multi_index;
using container=multi_index_container<
int,
indexed_by<
hashed_unique<identity<int>,non_default_ctble_hash>
>
>;
int main()
{
container::ctor_args_list cal{
{0,identity<int>{},non_default_ctble_hash{666},std::equal_to<int>{}}
};
container c(cal);
}