I'm trying to extend an example I found in Koenig and Moo's "Accelerated C++." I've got the following code which attempts to split a vector into two partitions.
#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);
}
I get an error when I attempt to compile this file with 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
Obviously this is a toy example, but I've checked the function prototypes and I'm not sure where I'm going wrong here. Any suggestions?
You'll need to use mem_fun
to turn the member function into an function object, then use bind1st
to supply the this
pointer.
I was never particularly successful getting this stuff to work on a regular basis (the standard library algorithms seem to be mainly designed for use with freestanding functions or hand-written predicate classes), but something like this should do the trick:
vector<MyClass>::iterator it =
stable_partition(main.begin(),
main.end(),
bind1st(mem_fun(&AnalyzeMemOps::sameBaseReg),
this));
mem_fun
gives you back a function object that takes two arguments, the first being the object to invoke mem_fun
's member function on, and the second being the single argument to the member function.
bind1st
takes a function object that takes two arguments, and returns you a new one that takes one argument, which when invoked via operator()
will call the original function object with the bind1st
's argument as its first argument and the supplied argument as the second.
The end result is that a new function object is created, that takes one argument, and that will call this->sameBaseReg
, passing in the supplied argument.
The problem is that sameBaseReg
is a member function of AnalyzeMemOps
. You can't use it like an ordinary non-member function because it can only be called on an object.
If you have a modern compiler that supports C++0x, C++ TR1, or if you have Boost handy, you can use bind
to bind the pointer to member function to the this
object:
std::bind(&AnalyzeMemOps::sameBaseReg, this, std::placeholders::_1)
In the current C++ standard library, the <functional>
library has std::mem_fun
, std::bind1st
, and other functions that can help with this, but they are an absolute beating to use effectively.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.