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

时间:2013-06-03 16:25:55

标签: c++ algorithm stl

我的代码的基本结构是

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字符串是准确的)。

3 个答案:

答案 0 :(得分:4)

std::sort期望二元谓词在这种情况下采用两个整数。成员函数采用隐式的第一个参数,因此在所有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));
  }
  ...
};

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

答案 2 :(得分:1)

如何将对象用作比较器本身。这在gcc 4.6上编译:

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));
  }
};