我有一个有地图的班级。我需要通过搜索特定值,密钥的instad来在map中找到迭代器。使用成员函数谓词IsValueFound,我正在尝试这个。
class A
{
public:
void findVal();
private:
int state;
map<int, int> exmap;
bool IsValueFound(pair<int key, int val> itr)
{
return state == itr.second;
}
};
void A::findVal
{
itr = find_if(exmap.begin, exmap.end, mem_fun1_ref(&A::IsValueFound));
}
我遇到了编译错误。我不确定这些功能适配器的语法是什么。请帮忙。
编辑:抱歉。请忽略finf_if stmt以外的编译错误。我需要先修改find_if stmt。代码也没有提升:(答案 0 :(得分:4)
将对象A转换为仿函数更容易:
但是您的代码还存在其他问题(见下文):
#include <map>
#include <memory>
#include <functional>
#include <algorithm>
using namespace std;
class A {
public:
void findVal();
private:
int state;
map<int, int> exmap;
// Changed the function IsValueFound() to operator()
// This makes the whole object behave like a function.
// Its a lot easier then getting member functions and binding
// the this reference.
bool operator()(map<int,int>::value_type const& itr) const
// ^^^^^^^^^^^^^^^^^
// std::pair<int,int> is not the type held in the map
// so you are not going to bind against it using a pair.
{
return state == itr.second;
}
};
void A::findVal()
{
// You did not specify a type
// for the iterator in your code.
std::map<int,int>::iterator itr1 = find_if(exmap.begin(), exmap.end(), *this);
// ^^^^^^ ^^^^^^
// begin() and end() are methods.
// Just pass the `this` object as the the third parameter it will act as a function now.
}
答案 1 :(得分:3)
修改:我的答案显然有错误,mem_fun1_ref(&A::IsValueFound)
不能用作std::find_if
的谓词。我正在努力纠正这个问题。
您忘记了exmap.begin
和exmap.end
的括号。
我想如果你已经阅读了编译错误报告,它会告诉它一些事情。
我会这样写:
typedef map<int, int>::const_iterator MyIterator
void A::findVal()
{
const MyIterator itrBegin = exmap.begin();
const MyIterator itrEnd = exmap.end();
MyIterator itrFound = find_if( itrBegin ,
itrEnd ,
mem_fun1_ref(&A::IsValueFound));
}
但我没有尝试mem_fun1_ref(&A::IsValueFound)
进行编译。而且我不习惯使用mem_fun1_ref
,我总是用operator()
重新定义我自己的仿函数。
答案 2 :(得分:2)
如果您不想使用Boost Bimap,您可以创建一个所谓的仿函数,一个重载函数调用操作符()
的对象。在这段代码中:
class A {
public:
bool findVal(int s);
private:
map<int, int> exmap;
struct IsValueFound {
int state;
IsValueFound(int _state) : state(_state) {};
bool operator()(const pair<int, int>& itr) {
return state == itr.second;
}
};
};
bool A::findVal(int x) {
return (find_if(exmap.begin(), exmap.end(), A::IsValueFound(x)) != exmap.end());
}
答案 3 :(得分:1)
至于编译错误,你在IsValueFound的参数列表中声明你的迭代器是错误的。它应该是:
map<int, int>::iterator itr
然后在A :: findVal中根本没有声明它。
话虽如此,如果您需要经常这样做,扫描地图中的值并不是一个好主意。您应该考虑数据的其他内部表示。
答案 4 :(得分:1)
mem_fun_ref
采用你的一个参数函数
bool IsValueFound(pair<int, int> itr)
并将其转换为两个参数仿函数:
bool functor(A& this, pair<int, int> itr)
。
其中用作第一个参数的引用用于生成this
指针以调用成员函数IsValueFound
。
你可能不希望这里有任何 mem_fun_ref
- 绑定器可以正常工作:
std::find_if(exmap.begin, exmap.end, std::bind2nd(std::equal_to<int>(), state));
刚才意识到这对地图迭代器不起作用......我可能只是在这一点上编写一个显式循环。
你也有一些语法错误,但是@martona已经触及了它们,所以我不会打败死马:)
答案 5 :(得分:0)
您实际上将地图用作bi-directional map
,因此您可能会发现提升Boost Multi-index Containers非常有用。他们有一个实现双向地图的具体例子。
答案 6 :(得分:0)
只需使用Boost Bimap。