Nav*_*vid 30 c++ sorting stl compiler-errors
试图编译以下代码我得到这个编译错误,我该怎么办?
ISO C++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针.
class MyClass {
int * arr;
// other member variables
MyClass() { arr = new int[someSize]; }
doCompare( const int & i1, const int & i2 ) { // use some member variables }
doSort() { std::sort(arr,arr+someSize, &doCompare); }
};
Run Code Online (Sandbox Code Playgroud)
And*_*nck 28
doCompare一定是static.如果您doCompare需要的数据MyClass可以MyClass通过更改来变成比较仿函数:
doCompare( const int & i1, const int & i2 ) { // use some member variables }
Run Code Online (Sandbox Code Playgroud)
成
bool operator () ( const int & i1, const int & i2 ) { // use some member variables }
Run Code Online (Sandbox Code Playgroud)
并致电:
doSort() { std::sort(arr,arr+someSize, *this); }
Run Code Online (Sandbox Code Playgroud)
还有,是不是doSort错过了返回值?
我认为应该可以使用std::mem_fun和某种绑定将成员函数转换为自由函数,但确切的语法现在避开了我.
编辑: Doh,std::sort按值来获取仿函数,这可能是个问题.为了解决这个问题,请将类中的仿函数包装起来:
class MyClass {
struct Less {
Less(const MyClass& c) : myClass(c) {}
bool operator () ( const int & i1, const int & i2 ) {// use 'myClass'}
MyClass& myClass;
};
doSort() { std::sort(arr,arr+someSize, Less(*this)); }
}
Run Code Online (Sandbox Code Playgroud)
Kla*_*aim 13
正如Andreas Brinck所说,doCompare必须是静态的(+1).如果你必须在比较器函数中有一个状态(使用该类的其他成员),那么你最好使用函子而不是函数(这会更快):
class MyClass{
// ...
struct doCompare
{
doCompare( const MyClass& info ) : m_info(info) { } // only if you really need the object state
const MyClass& m_info;
bool operator()( const int & i1, const int & i2 )
{
// comparison code using m_info
}
};
doSort()
{ std::sort( arr, arr+someSize, doCompare(*this) ); }
};
Run Code Online (Sandbox Code Playgroud)
使用仿函数总是更好,输入时间更长(可能不方便但很好......)
我认为你也可以使用std :: bind和成员函数,但我不知道怎么回事并不容易.
更新2014:今天我们可以访问c ++ 11编译器,因此您可以使用lambda代码,代码会更短但具有完全相同的语义.
Rob提出的解决方案现在是有效的C++ 11(不需要Boost):
void doSort()
{
using namespace std::placeholders;
std::sort(arr, arr+someSize, std::bind(&MyClass::doCompare, this, _1, _2));
}
Run Code Online (Sandbox Code Playgroud)
事实上,正如Klaim所提到的,lambdas是一个选项,有点冗长(你必须"重复"参数是整数):
void doSort()
{
std::sort(arr, arr+someSize, [this](int l, int r) {return doCompare(l, r); });
}
Run Code Online (Sandbox Code Playgroud)
C++ 14支持auto:
void doSort()
{
std::sort(arr, arr+someSize, [this](auto l, auto r) {return doCompare(l, r); });
}
Run Code Online (Sandbox Code Playgroud)
但是,你仍然宣称参数是通过副本传递的.
然后问题是"哪一个是最有效的".这个问题由Travis Gockel处理:Lambda vs Bind.他的基准程序在我的计算机上提供(OS X i7)
Clang 3.5 GCC 4.9
lambda 1001 7000
bind 3716166405 2530142000
bound lambda 2438421993 1700834000
boost bind 2925777511 2529615000
boost bound lambda 2420710412 1683458000
Run Code Online (Sandbox Code Playgroud)
其中lambda是一个直接使用的lambda,lambda bound是一个存储在一个lambda中的lambda std::function.
所以看起来lambdas是一个更好的选择,这并不是一个惊喜,因为编译器提供了更高级别的信息,从中可以获利.
您可以使用boost::bind:
void doSort() {
std::sort(arr,arr+someSize, boost::bind(&MyClass::doCompare, this, _1, _2));
}
Run Code Online (Sandbox Code Playgroud)