需要访问类的私有成员的比较器



我的代码的基本结构是

class Foo{
  vector<string> _lines;
  vector<int> _n;
  public:
  ...
  bool Comp(int i, int j){
    return something that depends on _lines;
  }
  ...
  void doSomething(){
    std::sort(_n.begin(), _n.end(), Comp);
  }
  ...
};

但是我得到

error: no matching function for call to 
‘sort(std::vector<unsigned int>::iterator, 
std::vector<unsigned int>::iterator, <unresolved overloaded function type>)

如何解决这个问题不复制向量?(因为这些向量是非常非常大的17179508个字符串)。

std::sort期望一个二进制谓词在本例中接受两个int型。成员函数接受隐式的第一个参数,因此在所有Foo::Comp中接受三个参数。你可以传递一个非成员函数,或者一个静态成员函数,但是它们都不能访问Foo的数据成员。简单的方法是使用std::bindthis绑定到成员函数的第一个参数:

#include <functional> // for std::bind
#include <vector>
#include <algorithm>
class Foo{
  vector<string> _lines;
  vector<int> _n;
 public:
  ...
  bool Comp(int i, int j){
    return something that depends on _lines;
  }
  ...
  void sort(){
    using namespace std::placeholders;
    std::sort(_n.begin(), _n.end(), std::bind(Comp, this, _1, _2));
  }
  ...
};

最明显的初始建议是将intstring聚合到一个结构体或std::pair中,在其中具有聚合的单个向量,然后对聚合向量进行排序。

但如果这两个向量实际上是独立的,我建议使用外部谓词,而不是您的Comp方法的:

struct Comp
{
    explicit Comp(vector<string>& lines) : lines_(lines) { }
    bool operator()(int i, int j) const
    {
        return something that depends on lines_;
    }
    vector<string>& lines_;
};

然后调用:

void doSomething()
{
    std::sort(_n.begin(), _n.end(), Comp(_lines));
}

如何使用您的对象作为比较器本身。

class Foo{
  std::vector<std::string> _lines;
  std::vector<int> _n;
  public:
  bool operator()(int i, int j){
    return false;
  }
  void doSomething(){
    std::sort(_n.begin(), _n.end(), *this);
  }
};

编辑:

事实证明这不是一个好主意,复制一个有17M个字符串的对象会招致巨大的损失。可以使用带指针的嵌套类来代替。这也允许我们有不同的比较器:

class Foo
{
  std::vector<std::string> _lines;
  std::vector<int> _n;
  class Bar
  {
  public:
      Bar( const Foo * foo ) : _foo( foo ) {}
      bool operator()( int i, int j )
      {
          act on _foo->_lines
      }
  private:
      const Foo * _foo;
  };
public:
  void doSomething(){
    std::sort(_n.begin(), _n.end(), Bar(this));
  }
};

最新更新