如何在 C++ 中使用带有自定义排序成员函数的 sort()?
How to use sort() in C++ with custom sort member function?
我有一个关于将比较函数传递给 sort()
的问题。
我想要做的是定义一个 sort()
函数,该函数在计算时考虑了我要在其中进行排序的 class 的成员变量。
基本上,我的代码看起来像这样(经过简化只显示相关部分):
MappingTechnique.h
struct MappingTechnique {
vector<int> usedIndexCount;
};
struct SimpleGreedyMappingTechnique : MappingTechnique {
bool sortByWeights(int index1, int index2);
};
MappingTechnique.m
bool SimpleGreedyMappingTechnique::sortByWeights(int index1, int index2) {
return usedIndexCount[index1] > usedIndexCount[index2];
}
void SimpleGreedyMappingTechnique::processFrame(Frame frame) {
vector<int> payloadIndices = <generate the vector>
// sort the payload indices according to their current usedIndexCount
sort(payloadIndices.begin(), payloadIndices.end(), sortByWeights);
}
此代码无法编译,会出现以下错误:
error: reference to non-static member function must be called
并指向 sortByWeights
.
甚至可以使用 class 的成员函数进行排序吗?如果是,我该如何实现?
是的,但总的来说,我鼓励只使用适当的仿函数或 lambda:
使用 lambda:
std::sort(payloadIndices.begin(), payloadIndices.end(), [this](int a, int b){
return this->sortByWeights(a, b);
});
或者使用 std::mem_fn
:
auto sorter = std::bind(std::mem_fn(SimpleGreedyMappingTechnique::sortByWeights), this);
std::sort(payloadIndices.begin(), payloadIndices.end(), sorter);
或者使用仿函数:
namespace{
struct indicies_less_than
{
const SimpleGreedyMappingTechnique & mapping_tech;
indicies_less_than(const SimpleGreedyMappingTechnique & mapping_tech)
:mapping_tech(mapping_tech){}
bool operator()(int a, int b)
{
return mapping_tech.sortByWeights(a, b);
}
};
}
std::sort(payloadIndices.begin(), payloadIndices.end(), indicies_less_than(*this));
注:
如果要排序的类型比 int
更复杂,您肯定希望通过 const&
传递它们以防止复制
如 Mgetz 所述,可以使用函子。仿函数示例:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <vector>
#define asize 16
class example{
public:
unsigned int a[asize]; // array
std::vector<size_t> v; // indices to array
example(void)
{
v.resize(asize);
for(size_t i = 0; i < asize; i++){
a[i] = rand()%10;
v[i] = i;
}
}
void displayarray(void)
{
for(size_t i = 0; i < asize; i++)
std::cout << std::setw(3) << a[v[i]];
std::cout << std::endl;
}
class lessthan // lessthan functor for std::sort
{
public:
const example &x;
lessthan(const example &e ) : x(e) { }
bool operator()(const size_t & i0, const size_t & i1)
{
return x.a[i0] < x.a[i1];
}
};
void sortarray(void)
{
std::sort(v.begin(), v.end(), lessthan(*this));
}
};
int main()
{
example x;
x.displayarray();
x.sortarray();
x.displayarray();
return 0;
}
我有一个关于将比较函数传递给 sort()
的问题。
我想要做的是定义一个 sort()
函数,该函数在计算时考虑了我要在其中进行排序的 class 的成员变量。
基本上,我的代码看起来像这样(经过简化只显示相关部分):
MappingTechnique.h
struct MappingTechnique {
vector<int> usedIndexCount;
};
struct SimpleGreedyMappingTechnique : MappingTechnique {
bool sortByWeights(int index1, int index2);
};
MappingTechnique.m
bool SimpleGreedyMappingTechnique::sortByWeights(int index1, int index2) {
return usedIndexCount[index1] > usedIndexCount[index2];
}
void SimpleGreedyMappingTechnique::processFrame(Frame frame) {
vector<int> payloadIndices = <generate the vector>
// sort the payload indices according to their current usedIndexCount
sort(payloadIndices.begin(), payloadIndices.end(), sortByWeights);
}
此代码无法编译,会出现以下错误:
error: reference to non-static member function must be called
并指向 sortByWeights
.
甚至可以使用 class 的成员函数进行排序吗?如果是,我该如何实现?
是的,但总的来说,我鼓励只使用适当的仿函数或 lambda:
使用 lambda:
std::sort(payloadIndices.begin(), payloadIndices.end(), [this](int a, int b){
return this->sortByWeights(a, b);
});
或者使用 std::mem_fn
:
auto sorter = std::bind(std::mem_fn(SimpleGreedyMappingTechnique::sortByWeights), this);
std::sort(payloadIndices.begin(), payloadIndices.end(), sorter);
或者使用仿函数:
namespace{
struct indicies_less_than
{
const SimpleGreedyMappingTechnique & mapping_tech;
indicies_less_than(const SimpleGreedyMappingTechnique & mapping_tech)
:mapping_tech(mapping_tech){}
bool operator()(int a, int b)
{
return mapping_tech.sortByWeights(a, b);
}
};
}
std::sort(payloadIndices.begin(), payloadIndices.end(), indicies_less_than(*this));
注:
如果要排序的类型比 int
更复杂,您肯定希望通过 const&
传递它们以防止复制
如 Mgetz 所述,可以使用函子。仿函数示例:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <vector>
#define asize 16
class example{
public:
unsigned int a[asize]; // array
std::vector<size_t> v; // indices to array
example(void)
{
v.resize(asize);
for(size_t i = 0; i < asize; i++){
a[i] = rand()%10;
v[i] = i;
}
}
void displayarray(void)
{
for(size_t i = 0; i < asize; i++)
std::cout << std::setw(3) << a[v[i]];
std::cout << std::endl;
}
class lessthan // lessthan functor for std::sort
{
public:
const example &x;
lessthan(const example &e ) : x(e) { }
bool operator()(const size_t & i0, const size_t & i1)
{
return x.a[i0] < x.a[i1];
}
};
void sortarray(void)
{
std::sort(v.begin(), v.end(), lessthan(*this));
}
};
int main()
{
example x;
x.displayarray();
x.sortarray();
x.displayarray();
return 0;
}