3

我的代码的基本结构是

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 个字符串)。

4

3 回答 3

4

std::sort在这种情况下,期望二元谓词采用两个整数。成员函数采用隐式的第一个参数,因此总共Foo::Comp采用三个参数。您可以传递非成员函数或静态成员函数,但它们都无法访问Foo的数据成员。最简单的方法是使用std::bind绑定this到成员函数的第一个参数:

#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));
  }
  ...
};
于 2013-06-03T16:28:38.980 回答
2

最明显的初始建议是将你的intand聚合string成一个结构体 or 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));
}
于 2013-06-03T16:40:13.483 回答
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));
  }
};
于 2013-06-03T16:45:10.020 回答