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

时间:2018-04-05 09:58:46

标签: c++ lambda string-comparison case-insensitive unordered-set

目标:需要boost :: 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函数而不是functor创建这个类成员。

2 个答案:

答案 0 :(得分:3)

也许这就是你要找的东西:

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();
}

答案 1 :(得分:0)

让类成员类型依赖于lambdas是痛苦的,我不会推荐它。在这种情况下,它可能最容易去#34; old&#34;使用仿函数类而不是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;
}

你可以做另一个答案中建议的事情并模板包含hasher和相等比较器类型的集合的类,然后使用模板函数创建类的实例(以获得模板演绎),但那是非常具有侵入性,并且使包含该集合的类难以在任何地方使用 - 特别是,如果需要将该类作为某个成员,那么将再次出现

您是否有任何特殊原因要避免仿函数类?