gpt4 book ai didi

c++ - STL find_if 和不区分大小写的字符串比较

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:35:29 32 4
gpt4 key购买 nike

我有一个 Models 的 vector ,如下所示:

struct Model
{
std::string mName;
// .......
};

给定一个表示模型名称的字符串,我想看看是否可以在 vector 中找到其中一个模型。

现在我有这个:

std::string assetName = "monkey";
std::vector<Model>::iterator iter = std::find_if(mModels.begin(), mModels.end(), boost::bind(&Model::mName, _1) == assetName);

但是这不会进行不区分大小写的字符串比较。所以我阅读了有关 boost/algorithm/string.hpp 的内容,其中包含 boost::iequals,它正确地做到了这一点。

这是我使用它的尝试:

std::vector<Model>::iterator iter = std::find_if(mModels.begin(), mModels.end(), boost::iequals(boost::bind(&Model::mName, _1), assetName));

然而,这并没有编译并报告了数百行编译错误。我相信 std::find_if 期望第三个参数函数只有 1 个参数。

是否有解决此问题的简单方法?

编辑:我忘了说我不能使用 C++11,但我可以使用 boost!

EDIT2:下面的答案似乎给我这个编译错误,使用这个:

std::vector<Model>::iterator iter = std::find_if(mModels.begin(), mModels.end(), boost::bind(&boost::iequals<std::string, std::string>, boost::bind(&Model::mName, _1), assetName));


bind.hpp(69): error C2825: 'F': must be a class or namespace when followed by '::'
2> bind\bind_template.hpp(15) : see reference to class template instantiation 'boost::_bi::result_traits<R,F>' being compiled
2> with
2> [
2> R=boost::_bi::unspecified,
2> F=bool (__cdecl *)(const std::string &,const std::string &,const std::locale &)
2> ]
2> resourcemanifest.cpp(24) : see reference to class template instantiation 'boost::_bi::bind_t<R,F,L>' being compiled
2> with
2> [
2> R=boost::_bi::unspecified,
2> F=bool (__cdecl *)(const std::string &,const std::string &,const std::locale &),
2> L=boost::_bi::list2<boost::_bi::bind_t<const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &,boost::_mfi::dm<std::string,Model>,boost::_bi::list1<boost::arg<1>>>,boost::_bi::value<std::string>>
2> ]

最佳答案

调用而不是绑定(bind)函数

boost::iequals(boost::bind(&Model::mName, _1), assetName)

绑定(bind)是一个转移注意力的问题:这目前不是仿函数,而是函数调用。

您(不小心)试图立即调用它,并使用 bool 值 result 作为 std::find_if 的比较函数。当然,这是不正确的。

您绑定(bind)模型名称是正确的,但您仍然必须将实际调用也绑定(bind)到 iequals

这是 a prior example on the Boost users' mailing list - bind iequals 的第一个 Google 结果。

尝试这样的事情:

boost::bind(
&boost::iequals<std::string,std::string>,
boost::bind(&Model::mName, _1), // 1st arg to iequals
assetName, // 2nd arg to iequals
std::locale() // 3rd arg to iequals
)

请注意,模板参数推导在这里是不可能的;另请注意,我们必须显式提供 boost::iequals 的默认第三个参数,因为默认值不会为我们提供在绑定(bind)函数时能够省略参数的魔力。

完整的工作测试用例:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/algorithm/string/predicate.hpp>

struct Model
{
Model(const std::string& name) : name(name) {};
std::string mName() const
{
return name;
}

private:
std::string name;
};

int main()
{
std::vector<Model> mModels;
mModels.push_back(Model("a"));
mModels.push_back(Model("b"));
mModels.push_back(Model("c"));

const std::string assetName = "B";

std::vector<Model>::iterator it = std::find_if(
mModels.begin(),
mModels.end(),
boost::bind(
&boost::iequals<std::string,std::string>,
boost::bind(&Model::mName, _1),
assetName,
std::locale()
)
);

assert(it != mModels.end());
std::cout << it->mName() << std::endl; // expected: "b"
}

(实时查看 here 。)


那么,为什么我的原始代码可以工作?

boost::bind(&Model::mName, _1) == assetName 中,运算符 == 在与 boost::bind 一起使用时被重载 施展魔法;虽然它看起来像是在进行直接比较,但实际上并没有在 std::find_if 的参数中计算比较,而是推迟到稍后(主要是通过执行您看不到的隐式 bind

但是,在正常函数调用的情况下,例如 boost::iequals,我们必须自己应用那个“魔法”,这就是上面的全部内容。

关于c++ - STL find_if 和不区分大小写的字符串比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16315882/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com