我试图扩展我在Koenig和Moo的“Accelerated C ++”中找到的一个例子。我有以下代码尝试将矢量拆分为两个分区。
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct MyClass {
int* MyInt;
MyClass() : MyInt(NULL) {}
};
struct AnalyzeMemOps {
vector<MyClass> AllMyClassRecords; // Where I keep the MyClass instances
bool sameBaseReg(MyClass m);
vector<MyClass> splitBySameBase(vector<MyClass>& main);
AnalyzeMemOps() {}
};
// Predicate function for stable_partition
bool AnalyzeMemOps::sameBaseReg(MyClass m) {
return true;
}
vector<MyClass> AnalyzeMemOps::splitBySameBase(vector<MyClass>& main) {
vector<MyClass>::iterator it =
stable_partition(main.begin(), main.end(), sameBaseReg); // Error is here
vector<MyClass> sameBases(it, main.end());
main.erase(it, main.end());
// Print results
cout << "Split By Same Base: Returning SameBase Instrs\n";
for (vector<MyClass>::iterator i = sameBases.begin(); i != sameBases.end(); ++i) {
cout << " " << i->MyInt << "\n";
}
return sameBases;
}
int main() {
AnalyzeMemOps AMCR;
MyClass m;
AMCR.AllMyClassRecords.push_back(m);
AMCR.AllMyClassRecords.push_back(m);
AMCR.AllMyClassRecords.push_back(m);
vector<MyClass> t = AMCR.splitBySameBase(AMCR.AllMyClassRecords);
}
当我尝试使用g ++编译此文件时出现错误:
Tile.cpp: In member function \u2018std::vector<MyClass, std::allocator<MyClass> > AnalyzeMemOps::splitBySameBase(std::vector<MyClass, std::allocator<MyClass> >&)\u2019:
Tile.cpp:26: error: no matching function for call to \u2018stable_partition(__gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, __gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, <unresolved overloaded function type>)\u2019
/usr/include/c++/4.4/bits/stl_algo.h:1864: note: candidates are: _BIter std::stable_partition(_BIter, _BIter, _Predicate) [with _BIter = __gnu_cxx::__normal_iterator<MyClass*, std::vector<MyClass, std::allocator<MyClass> > >, _Predicate = bool (AnalyzeMemOps::*)(MyClass)]
make: *** [a.out] Error 1
显然这是一个玩具示例,但我检查了函数原型,我不确定我在哪里出错了。有什么建议吗?
答案 0 :(得分:3)
您需要使用mem_fun
将成员函数转换为函数对象,然后使用bind1st
提供this
指针。
我从来没有特别成功地让这些东西定期工作(标准库算法似乎主要设计用于独立函数或手写谓词类),但是像这样的东西应该可以解决这个问题: / p>
vector<MyClass>::iterator it =
stable_partition(main.begin(),
main.end(),
bind1st(mem_fun(&AnalyzeMemOps::sameBaseReg),
this));
mem_fun
返回一个带有两个参数的函数对象,第一个是调用mem_fun
的成员函数的对象,第二个是成员函数的单个参数。 / p>
bind1st
接受一个带有两个参数的函数对象,并返回一个带有一个参数的新对象,当通过operator()
调用时,将使用bind1st
调用原始函数对象将论证作为第一个参数,将提供的参数作为第二个参数。
最终结果是创建了一个新的函数对象,它接受一个参数,然后调用this->sameBaseReg
,传入提供的参数。
答案 1 :(得分:3)
问题是sameBaseReg
是AnalyzeMemOps
的成员函数。您不能像普通的非成员函数那样使用它,因为它只能在对象上调用。
如果你有一个支持C ++ 0x,C ++ TR1的现代编译器,或者你有方便的Boost,你可以使用bind
将指向成员函数的指针绑定到this
对象:
std::bind(&AnalyzeMemOps::sameBaseReg, this, std::placeholders::_1)
在当前的C ++标准库中,<functional>
库具有std::mem_fun
,std::bind1st
以及其他可以帮助解决此问题的函数,但它们绝对可以有效地使用。< / p>