在字符串的 boost::unordered_set 中使用 Lambda 函数 - 不区分大小写

Using Lambda function in boost::unordered_set of strings - case insensitive

本文关键字:函数 Lambda 不区 大小写 字符串 boost unordered set      更新时间:2023-10-16

目标:需要有字符串的提升::unordered_set - 不区分大小写。但是这个集合是一个类的成员变量。

如果它不是成员变量,我可以按如下方式创建此集合。它对我有用。

auto hash= [](const std::string& s) -> size_t
{
    size_t seed = 0;
    //Logic
    return seed;
};
auto equal= [](const std::string& s1, const std::string& s2)
{ 
    return boost::algorithm::iequals(s1, s2, std::locale());
};
typedef boost::unordered_set<std::string, decltype(hash), decltype(equal) > StringSet;

由于我的 boost::unordered_set 是一个类成员,我无法像上面那样定义它。

我如何使用 lambda 函数而不是函子创建这个类成员。

也许这就是你要找的:

https://wandbox.org/permlink/qz8mbCY57BNPbZEU

#include <string>
#include <boost/unordered_set.hpp>
#include <boost/algorithm/algorithm.hpp>
#include <boost/algorithm/string/predicate.hpp>
template <typename H, typename E>
struct my_class_with_member_set {
    boost::unordered_set<std::string, H, E > _set;
    my_class_with_member_set(std::size_t s, H h, E e):_set(s,std::move(h),std::move(e)){}
};
int main(){
    auto hash= [](const std::string& s) -> size_t
    {
        size_t seed = 0;
        //Logic
        return seed;
    };
    auto equal= [](const std::string& s1, const std::string& s2)
    { 
        return boost::algorithm::iequals(s1, s2, std::locale());
    };
    my_class_with_member_set my_class(42,hash,equal);
    my_class._set.insert("foo");
    my_class._set.insert("bar");

    return my_class._set.size();
}

--更新--

或:

https://wandbox.org/permlink/UWVV2puGXWXWLqvC

#include <string>
#include <boost/unordered_set.hpp>
#include <boost/algorithm/algorithm.hpp>
#include <boost/algorithm/string/predicate.hpp>
class my_class_with_member_set {
    constexpr static auto hash= [](const std::string& s) -> size_t
    {
        size_t seed = 0;
        //Logic
        return seed;
    };
    constexpr static auto equal= [](const std::string& s1, const std::string& s2)
    { 
        return boost::algorithm::iequals(s1, s2, std::locale());
    };
public:
    boost::unordered_set<std::string, decltype(hash), decltype(equal) > _set;
    my_class_with_member_set(std::size_t s):_set(s,hash,equal){}
};
int main(){
    my_class_with_member_set my_class(42);
    my_class._set.insert("foo");
    my_class._set.insert("bar");

    return my_class._set.size();
}

让类成员类型依赖于 lambda 是痛苦的,我不推荐它。在这种情况下,最简单的方法是使用函子类而不是lambda的"旧"路线(我知道你想避免它,但任何其他解决方案都复杂得多(:

struct MyHasher
{
    size_t operator()(std::string& s) const
    {
        size_t seed = 0;
        //Logic
        return seed;
    }
}
struct MyEqual
{
    size_t operator()(const std::string& s1, const std::string& s2) const
    {
        return boost::algorithm::iequals(s1, s2, std::locale());
    }
}
class MyClassWithSet
{
    boost::unordered_set<std::string, MyHasher, MyEqual> _set;
}

您可以执行其他答案中建议的操作,并模板化包含哈希器和相等比较器类型的集合的类,然后使用模板函数创建类的实例(以获得模板推论(,但这非常具有侵入性,并且使包含集合的类难以在任何地方使用 - 特别是, 如果在某处需要该类作为成员,您将再次遇到同样的问题。

有什么特别的原因要避免函子类吗?