代码之家  ›  专栏  ›  技术社区  ›  Zeke

C++稳定分区编译器错误

  •  2
  • Zeke  · 技术社区  · 15 年前

    我试图扩展我在KoeNIG和Moo的“加速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 回复  |  直到 15 年前
        1
  •  3
  •   James McNellis    15 年前

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

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

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

    在当前的C++标准库中, <functional> 图书馆有 std::mem_fun , std::bind1st ,以及其他有助于解决此问题的功能,但它们绝对是一种有效使用的优势。

        2
  •  3
  •   please delete meplease delete me    15 年前

    你需要使用 mem_fun 若要将成员函数转换为函数对象,请使用 bind1st 提供 this 指针。

    我从未特别成功地让这些东西定期工作(标准库算法似乎主要设计用于独立函数或手工编写的谓词类),但类似的东西应该能做到:

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

    好玩的 返回一个带两个参数的函数对象,第一个参数是要调用的对象 好玩的 的成员函数,第二个是成员函数的单个参数。

    绑定1 接受接受两个参数的函数对象,并返回一个接受一个参数的新函数对象,当通过 operator() 将使用 绑定1 的参数作为第一个参数,提供的参数作为第二个参数。

    最终的结果是创建了一个新的函数对象,该对象接受一个参数,并将调用 this->sameBaseReg ,传入提供的参数。