Ошибка компилятора C ++ stable_partition - PullRequest
2 голосов
/ 25 ноября 2010

Я пытаюсь расширить пример, который нашел в Кениге и Му "Ускоренный 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 ]

3 голосов
/ 25 ноября 2010

Проблема в том, что sameBaseReg является функцией-членом AnalyzeMemOps.Вы не можете использовать ее как обычную функцию, не являющуюся членом, потому что она может быть вызвана только для объекта.

Если у вас есть современный компилятор, который поддерживает C ++ 0x, C ++ TR1 или Boostудобно, вы можете использовать bind для привязки указателя на функцию-член к объекту this:

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

В текущей стандартной библиотеке C ++ библиотека <functional> имеет std::mem_fun, std::bind1st и другие функции, которые могут помочь с этим, но они являются абсолютным преимуществом для эффективного использования.

3 голосов
/ 25 ноября 2010

Вам нужно будет использовать mem_fun, чтобы превратить функцию-член в функциональный объект, затем используйте bind1st, чтобы указать указатель this.

Мне никогда особенно не удавалось заставить этот материал работать на регулярной основе (стандартные алгоритмы библиотеки, кажется, в основном предназначены для использования с автономными функциями или рукописными классами предикатов), но что-то вроде этого должно сработать: 1006 *

vector<MyClass>::iterator it =
    stable_partition(main.begin(),
                     main.end(),
                     bind1st(mem_fun(&AnalyzeMemOps::sameBaseReg),
                             this));

mem_fun возвращает вам объект функции, который принимает два аргумента, первый из которых является объектом для вызова функции-члена mem_fun, а второй - единственным аргументом функции-члена.

bind1st принимает объект функции, который принимает два аргумента, и возвращает вам новый, который принимает один аргумент, который при вызове через operator() будет вызывать исходный объект функции с аргументом bind1st в качестве первого аргумент и предоставленный аргумент как второй.

Конечным результатом является то, что создается новый объект функции, который принимает один аргумент и будет вызывать this->sameBaseReg, передавая предоставленный аргумент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...