我的代码的基本结构是
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::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));
}
...
};
最明显的初始建议是将int
和string
聚合到一个结构体或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));
}
};