Kai*_*aan 5 c++ string boost c++03
我有一个Models类似下面的矢量:
struct Model
{
std::string mName;
// .......
};
Run Code Online (Sandbox Code Playgroud)
给定一个表示模型名称的字符串,我想看看是否可以在向量中找到其中一个模型.
现在我有这个:
std::string assetName = "monkey";
std::vector<Model>::iterator iter = std::find_if(mModels.begin(), mModels.end(), boost::bind(&Model::mName, _1) == assetName);
Run Code Online (Sandbox Code Playgroud)
但这不会做不区分大小写的字符串比较.所以我读到了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));
Run Code Online (Sandbox Code Playgroud)
然而,这不会编译并报告数百行编译错误.我相信std :: find_if期望第三个param函数只有一个参数.
有一个简单的解决方案吗?
编辑:我忘了提到我不能使用C++ 11,但我可以使用提升!
编辑2:下面的答案似乎给我这个编译错误,使用这个:
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> ]
Run Code Online (Sandbox Code Playgroud)
boost::iequals(boost::bind(&Model::mName, _1), assetName)
Run Code Online (Sandbox Code Playgroud)
绑定是一个转移注意力的事情:这当前不是一个函子,而是一个函数调用。
您(意外地)尝试立即调用它,并将布尔结果用作 的比较函数std::find_if。当然,这是不正确的。
您绑定模型名称是正确的,但您仍然必须将实际调用绑定到iequals。
这是Boost 用户邮件列表中的一个先前示例- 第一个 Google 结果bind iequals。
尝试类似的方法:
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
)
Run Code Online (Sandbox Code Playgroud)
请注意,模板参数推导在这里是不可能的;还请注意,我们必须boost::iequals显式提供默认的第三个参数,因为默认值并没有为我们提供在绑定函数时能够省略参数的魔力。
完整的工作测试用例:
#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"
}
Run Code Online (Sandbox Code Playgroud)
(在这里查看它的实时工作情况。)
在 中,当与to do magicboost::bind(&Model::mName, _1) == assetName一起使用时,运算符==会重载;尽管看起来您正在进行直接比较,但该比较实际上并未在 的参数中进行评估,而是推迟到稍后(本质上是通过执行您看不到的隐式)。boost::bindstd::find_ifbind
然而,在普通函数调用的情况下,例如 to boost::iequals,我们必须自己应用这个“魔法”,这就是上面的内容。
| 归档时间: |
|
| 查看次数: |
1955 次 |
| 最近记录: |