// TEMPLATE STRUCT less
template<class _Ty>
struct less
: public binary_function<_Ty, _Ty, bool>
{ // functor for operator<
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
//////////// 使用缺省比较类型的情况:
以上是set第二个模板参数的定义。这个模板参数是一个比较类型即less<_Ty>,_Ty是set的第一个模板参数即key的类型。在使用set的时候可以只填第一个模板参数,而第二个参数就缺省的使用less<_Ty>。由于在less<_Ty>的定义中有return (_Left < _Right),所以类型_Ty必须支持operator<运算,即必须有这个函数的定义。比如这样使用set:
set<int> test_set; 这里的_Ty就是int,由于它本身就支持operator<,所以无需再定义。
set<MyStruct> test_set; 这里的_Ty就是MyStruct,它是一个自定义类型,所以这个类型要提供operator<函数的定义,如:
struct MyStruct
{
int m_data;
MyStruct( int data ) : m_data(data) {}
// 实现operator<
bool operator<(const MyStruct & otherStruct ) const
{
return m_data < otherStruct.m_data;
}
};
当然struct也可以改为class,但要加上public权限。
/////////// 自定义比较类型的情况:
在使用set的时候,也可以把第二个模板参数也填上而不使用缺省的less<_Ty>。这时候要模仿less<_Ty>定义自己的比较类型。比如:
#include <set>
#include <iostream>
using namespace std;
struct MyStruct // key type
{
int m_data;
MyStruct( int data ) : m_data(data) {}
bool operator<( const MyStruct & otherStruct ) const
{
return m_data < otherStruct.m_data;
}
};
template<typename _Ty>
struct CompareType // 也可以像less<_Ty>那样继承binary_function<...>类型,这里不这样做
{
bool operator( )( const _Ty & leftStruct, const _Ty & rightStruct ) const
{
return leftStruct < rightStruct;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
set<MyStruct, CompareType<MyStruct>> test_set;
test_set.insert( MyStruct(12) );
test_set.insert( MyStruct(12) );
cout << test_set.size() << endl;
set<MyStruct, CompareType<MyStruct>>::iterator it = test_set.begin();
for ( ; it != test_set.end(); ++ it )
{
cout << it->m_data << endl;
}
return 0;
}
以上的比较类型也可以简单的写成这样:
struct CompareType
{
bool operator( )( const MyStruct & leftStruct, const MyStruct & rightStruct ) const
{
return leftStruct.m_data < rightStruct.m_data;
}
};
而对于关键字的类型即_Ty,也可以是一些已知的类型,如string*等。比如:
#include <set>
#include <iostream>
#include <string>
using namespace std;
struct CompareType
{
bool operator( )( const string* leftPtr, const string* rightPtr ) const
{
return *leftPtr < *rightPtr; // string支持operator<
}
};
int _tmain(int argc, _TCHAR* argv[])
{
set<string*, CompareType> test_set;
test_set.insert( new string("blue") );
test_set.insert( new string("sky") );
test_set.insert( new string("cooking") );
cout << test_set.size() << endl;
set<string*, CompareType>::iterator it = test_set.begin();
for ( ; it != test_set.end(); ++ it )
{
cout << **it << endl;
delete *it;
}
return 0;
}
比较类型要定义的是关键字类型的比较函数。
比较函数定义的是严格的递增或递减的排序顺序,所以在两个关键字相等时不能返回true而必须返回false,否则会破坏容器,在加入相同元素时引发运行时错误。比如这样写是错误的:
struct CompareType // 比较类
{
bool operator( )( const string* leftPtr, const string* rightPtr ) const
{
return *leftPtr <= *rightPtr; // 错误!==时只能返回false
}
};
这个规则对于map,multiset和multimap同样适用。