很快就会明白,我还在学习C ++ 对于我正在处理的问题,我有一个类,它有一个std :: map数据成员和一些在地图上运行的成员函数。我将需要一些实例,其中地图按升序排序,而一些实例的地图按降序排序。对于这两种情况,成员函数的代码都是相同的(除了类型问题 - 正如我所知,更改映射的比较函数会改变其类型)。我正在努力完成这项工作,而不必为每个案例重写功能。
这里有一些玩具代码,我希望能说明我的情况(内联功能只是为了紧凑):
class MyClass {
public:
map<int, int>::iterator get_top(){ return data.begin(); }
int sum_elements(){
int sum = 0;
for ( map<int,int>::iterator it = data.begin(); it != data.end(); ++it){
sum += it->second;
}
}
};
理想情况下,我会有一个定义函数的基类和两个定义数据成员的派生类,一个用于升序,一个用于降序:
class Ascending : public MyClass {
private:
std::map<int, int, std::less<int> > data;
};
class Descending : public MyClass {
private:
std::map<int, int, std::greater<int> > data;
};
但是当然这不起作用,因为基类需要定义数据成员才能对其进行操作。 “简单”的出路是拥有两个独立的类,并将成员函数复制/粘贴到两者中。但这会浪费,我觉得C ++必须有一个优雅的解决方案来解决我的问题。
答案 0 :(得分:1)
定义一个重载operator()(int, int)
(比较)的仿函数,并将构造函数作为对元素进行排序的顺序。这样,您就可以定义地图
作为std::map<int, int, SortCriterion> data(comp)
,其中comp
定义为SortCriterion comp(true)
,例如升序,SortCriterion comp(false)
定义为降序。这样,两个地图都将具有相同的类型map<int, int, SortingCriterion>
。
以下代码:
#include <map>
#include <iostream>
using namespace std;
class SortCriterion
{
bool ascending;
public:
SortCriterion(bool sorting_type): ascending(sorting_type){};
bool operator()(int x, int y) const
// if not marked const,
// clang++ spits a compile-time error on insert
// however g++ compiles it ok
{
if(ascending) // ascending
return x<y;
else
return x>y;
}
};
int main()
{
// Both maps below have the SAME type, map<int, int, SortCriterion>
map<int, int, SortCriterion> m1(SortCriterion(true)); // ascending
map<int, int, SortCriterion> m2(SortCriterion(false)); // descending
m1.insert({1,1});
m1.insert({2,2});
m2.insert({1,1});
m2.insert({2,2});
cout << "First map:" << endl;
for(auto elem: m1)
cout << "[" << elem.first << "," << elem.second\
<< "]" << endl;
cout << endl << "Second map:" << endl;
for(auto elem: m2)
cout << "[" << elem.first << "," << elem.second\
<< "]" << endl;
}