C ++ stable_partition编译器错误

时间:2010-11-25 01:02:13

标签: c++ algorithm

我试图扩展我在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

显然这是一个玩具示例,但我检查了函数原型,我不确定我在哪里出错了。有什么建议吗?

2 个答案:

答案 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)

问题是sameBaseRegAnalyzeMemOps的成员函数。您不能像普通的非成员函数那样使用它,因为它只能在对象上调用。

如果你有一个支持C ++ 0x,C ++ TR1的现代编译器,或者你有方便的Boost,你可以使用bind将指向成员函数的指针绑定到this对象:

std::bind(&AnalyzeMemOps::sameBaseReg, this, std::placeholders::_1)

在当前的C ++标准库中,<functional>库具有std::mem_funstd::bind1st以及其他可以帮助解决此问题的函数,但它们绝对可以有效地使用。< / p>