这似乎是一个学术问题,但我仍然对答案非常感兴趣:
我有一个字符串s
的向量,我希望在其中找到给定的字符串findme
。这可以使用像
find(s.begin(), s.end(), findme);
我的问题是:必须有一种方法可以使用find_if
和STL字符串的compare
方法作为谓词,但是如何做?像
find_if(s.begin(), s.end(), bind2nd(mem_fun_ref(&string::compare), string("findme")) );
不起作用,因为compare方法有几个重载,编译器不知道选择哪一个。
作为第二步:我使用find_if而不是find的动机是我有一个从具有字符串属性name
的类派生的对象向量,我想找到一个具有给定名称的对象。这是否可行(没有编写额外的函数用作谓词)?
编辑:正如使用Boost提到的一些(大多数:)答案 - 我宁愿不必为此包含Boost。 (据我所知,大多数Boost库都是“唯一”模板,因此应该有一种不使用Boost的方法。)
答案 0 :(得分:5)
一个选项是将成员函数指针强制转换为合适的类型。你要忘记的另一件事是std :: string :: compare对于相等的字符串返回0,所以你还需要否定functor。总而言之:
std::find_if(
vec.begin(), vec.end(),
std::not1(
std::bind2nd(
std::mem_fun_ref(static_cast<int (std::string::*)(const char*)const>(&std::string::compare)),
"findme"
)
)
);
关于反对提升的理由:它的模板比STL功能头中的模板更灵活。它要么是提升,要么等待C ++ 0x lambdas(我相信在这种情况下会是更好的方式)或者你自己写一些助手。目前它不能简单:
std::find_if(vec.begin(), vec.end(), boost::bind(&X::name, _1) == "findme");
仅供参考,C ++ 0x将添加std :: bind,类似于boost :: bind,但似乎重载operator ==的便利性不会出现。
答案 1 :(得分:3)
自己选择正确的过载。
int (string::*compare)(const string&) const;
compare = &string::compare;
find_if(s.begin(), s.end(), bind2nd( mem_fun_ref(compare), string("findme")));
但是你会对引用问题“有效STL的第50项”的引用感到困惑。 而boost.Bind lib或boost.Lambda就是解决方案。
int (string::*compare)(const string&) const;
compare = &string::compare;
find_if(s.begin(), s.end(), bind(compare, _1, "findme")==0);
或
find_if(s.begin(), s.end(), bind2nd(std::equal_to<string>(), string("findme")));
答案 2 :(得分:1)
如果某个函数有重载函数,您可以将该函数转换为正确的签名
(void (*)(int,int))(&f)
。
对于你的第二个问题,如果你使用boost,你可以做这样的事情,
find_if(s.begin(), s.end(), boost::bind(std::equal_to<string>(), boost::bind(&SomeClass::name, _1), name);
答案 3 :(得分:0)
我想你会发现,如果你试图将几个函数放在一起,语法会很快变得不合适。你尝试过这样的事吗?
find_if(s.begin(), s.end(), bind2nd(mem_fun_ref(&string::compare), "findme"));
这是否与char *
重载不匹配?