【发布时间】:2011-05-06 07:59:00
【问题描述】:
我正在尝试在 std::map 上使用 std::find_if,寻找与字符串匹配的特定对象,如下所示:
class MyString
{
public:
MyString() {}
MyString(const std::string& x) : m_x(x) {}
const std::string& value() const
{
return m_x;
}
private:
std::string m_x;
};
std::map<int,MyString> squaresS;
std::map<int,MyString>::iterator iIt;
squaresS[1] = MyString("1");
squaresS[2] = MyString("4");
squaresS[3] = MyString("9");
const std::string sTarget = "4";
iIt = std::find_if(squaresS.begin(), squaresS.end(),
boost::bind(std::equal_to<std::string>(),
boost::bind(&MyString::value,
boost::bind(&std::map<int,MyString>::value_type::second, _1)),
sTarget));
if (iIt != squaresS.end())
std::cout << "Found " << iIt->second.value() << std::endl;
else
std::cout << "Not Found" << std::endl;
执行这段代码的结果是Not Found;我希望 Found 4 被输出。但是,如果我使用整数做大致相同的事情,那么它可以工作,即输出是 Found 4:
class MyInteger
{
public:
MyInteger() {}
MyInteger(int x) : m_x(x) {}
int value() const
{
return m_x;
}
private:
int m_x;
};
std::map<int,MyInteger> squaresI;
std::map<int,MyInteger>::iterator sIt;
squaresI[1] = MyInteger(1);
squaresI[2] = MyInteger(4);
squaresI[3] = MyInteger(9);
int iTarget = 4;
sIt = std::find_if(squaresI.begin(), squaresI.end(),
boost::bind(std::equal_to<int>(),
boost::bind(&MyInteger::value,
boost::bind(&std::map<int,MyInteger>::value_type::second, _1)),
iTarget));
if (sIt != squaresI.end())
std::cout << "Found " << sIt->second.value() << std::endl;
else
std::cout << "Not Found" << std::endl;
我怀疑这与 std::equal_to 有关,但我不确定如何解决此问题。
【问题讨论】:
-
无关评论:有时我只是惊讶于人们会被这种可怕的难以理解的语法一步一步地陶醉的程度。可能是关于boost的沸腾青蛙故事。
-
@6502,我听到了...一个简单的函子会比这种绑定魔法更容易理解...
<sigh/> -
实际上你上面的
MyString代码对我有用:ideone.com/DZ0lx,你仍然应该添加一个适当的复制构造函数! -
@Nim:同意。 C++0x 几乎就在这里,几乎没有什么理由可以避免新代码中的新特性。当然,我有点害怕人们会用
algorithm和 lambdas 编写的那种代码,而for就足够了:想想 jQuery 对 JavaScript 开发所做的事情,你就会明白我的意思了。跨度> -
您的 MyString 代码也适用于 gcc-4.2.1