std::set
ソートされた二分木に値を格納するため、保持している値を比較する方法を知る必要があります。デフォルトではstd::less
、特殊化されていないユーザー定義型に対して を呼び出そうとする比較関数として使用されますoperator<
。したがって、オブジェクトを比較する方法をセットに伝える最も簡単な方法はoperator<
、クラスに を定義することです。
template <class T, class S>
class Property
{
public:
pair<T,S> p;
Property(T t, S s) { p = make_pair(t,s);}
bool operator<(const Property<T,S>& rhs) const
{
return p < rhs.p;
}
};
std::set
ただし、タイプを比較する方法は他にもあります。std::less
1 つは、クラスのテンプレートを特殊化することです。
namespace std {
template<typename T,typename S>
struct less<Property<T, S> >
{
bool operator()(const Property<T, S>& lhs, const Property<T,S>& rhs) const
{
return lhs.p < rhs.p;
}
};
}
もう 1 つは、既定の比較型を、正しいシグネチャを持つ関数、または正しいシグネチャを持つoperator()
定義済みのクラスに置き換えることです。これは、物事が醜くなり始めるところです。
// Comparison function
template<typename T, typename S>
bool property_less_function(const Property<T,S>& lhs, const Property<T,S>& rhs)
{
return lhs.p < rhs.p;
}
// Comparison functor
template<typename T, typename S>
struct PropertyLess
{
bool operator()(const Property<T,S>& lhs, const Property<T,S>& rhs) const
{
return lhs.p < rhs.p;
}
};
int main()
{
// Set using comparison function.
// Have to pass the function pointer in the constructor so it knows
// which function to call. The syntax could be cleaned up with some
// typedefs.
std::set<Property<std::string, std::string>,
bool(*)(const Property<std::string, std::string>&,
const Property<std::string, std::string>&)>
set1(&property_less_function<std::string, std::string>);
// Set using comparison functor. Don't have to pass a value for the functor
// because it will be default constructed.
std::set<Property<std::string, std::string>, PropertyLess<std::string, std::string> > set2;
}
どのような小なり関数を使用する場合でも、その関数は型の厳密な弱い順序付けを定義する必要があることに注意してください。