如何创建一个比较器以在不同的字段上进行比较。不同的字段可以有不同的类型(uint
或string
)。我应该使用T *
吗?
有必要减少代码长度。
template<typename T>
class ComparatorSelector
{
public:
struct CompareByLabel{
bool operator() ( const T & iRight, const T & iLeft )
{
return iRight->m_label > iLeft->m_label;
}
};
struct CompareByHouseNumber{
bool operator() ( const T & iRight, const T & iLeft )
{
return iRight->m_houseNumber > iLeft->m_houseNumber;
}
};
//...
};
template< class T, class C, typename W >
class SearchIndex
{
public:
SearchIndex() {}
void Build( std::vector< T > iElems, C iComparator, std::ofstream oStream )
{
std::map< T *, size_t> numbersOfElems;
for( class std::vector<T>::iterator it = iElems.begin(); it != iElems.end(); ++it){
m_elems.insert( &(*it));
numbersOfElems[&(*it)] = m_elems.end - it ;
}
oStream << m_elems.size();
for( class std::multiset< T * >::iterator it = m_elems.begin(); it!= m_elems.end(); ++it )
oStream << numbersOfElems[*it];
m_compareMode = iComparator;
}
//....
}
答案 0 :(得分:2)
您可以使用指向成员的指针来自定义比较器对象。更慢但更简单的方法是:
#include <iostream>
template <typename Type, typename Class>
class comparator
{
Type Class::*d_member;
public:
comparator(Type Class::*member): d_member(member) {}
bool operator()(Class const& object0, Class const& object1) const {
return object0.*(this->d_member) < object1.*(this->d_member);
}
};
template <typename Type, typename Class>
comparator<Type, Class>
make_comparator(Type Class::*member)
{
return comparator<Type, Class>(member);
}
int main()
{
typedef std::pair<int, double> pair;
pair p0(17, 3.14);
pair p1(42, 2.7);
std::cout << std::boolalpha
<< "first: " << make_comparator(&pair::first)(p0, p1) << ' '
<< "second: " << make_comparator(&pair::second)(p0, p1) << ' '
<< '\n';
}
由于此版本在运行时使用指向成员的指针,因此无法轻松内联,因此不会像您希望的那样快。该成员也可以嵌入到比较器的类型中,这使得它的使用有点烦人:
template <typename Type, typename Class, Type Class::*Member>
class comparator
{
public:
bool operator()(Class const& object0, Class const& object1) const {
return object0.*Member < object1.*Member;
}
};
int main()
{
typedef std::pair<int, double> pair;
pair p0(17, 3.14);
pair p1(42, 2.7);
std::cout << std::boolalpha
<< "first: " << comparator<int, pair, &pair::first>()(p0, p1) << ' '
<< "second: " << comparator<double, pair, &pair::second>()(p0, p1) << ' '
<< '\n';
}
答案 1 :(得分:0)
这是使用不同类型的不同字段的比较器示例:
#include <set>
using namespace std;
class House {
public:
string m_label;
int m_houseNumber;
};
class HouseCompare {
public:
bool operator()( const House& a, const House& b)
{
if (a.m_houseNumber>0 && b.m_houseNumber>0)
return a.m_houseNumber < b.m_houseNumber;
else if (a.m_houseNumber>0)
return false;
else if (b.m_houseNumber)
return true;
else
return a.m_label < b.m_label;
}
};
int main(int argc, char *argv[])
{
typedef multiset<House, HouseCompare> Houses;
Houses houses;
House house_data[] = {
{"foo", 1},
{"foo1", 0},
{"foo0", 0},
{"foo", 2}
};
houses.insert (house_data, house_data+sizeof(house_data)/sizeof(House));
for (Houses::iterator i = houses.begin (); i != houses.end (); ++i)
cout << i->m_houseNumber << ": " << i->m_label << endl;
return 0;
}
输出:
0: foo0
0: foo1
1: foo
2: foo